Earthwaves Earth Sciences Forum
Life's little surprises - Printable Version

+- Earthwaves Earth Sciences Forum (http://www.earthwaves.org/forum)
+-- Forum: Earthwaves (http://www.earthwaves.org/forum/forumdisplay.php?fid=16)
+--- Forum: Miscellaneous (http://www.earthwaves.org/forum/forumdisplay.php?fid=15)
+--- Thread: Life's little surprises (/showthread.php?tid=16)



Life's little surprises - Roger Hunter - 12-30-2013

TB just told me that int((6.3-6.2)*10) = 0.

I understand why but I thought TB was better than that.

Roger


RE: Life's little surprises - Skywise - 12-30-2013

(12-30-2013, 04:26 PM)Roger Hunter Wrote: TB just told me that int((6.3-6.2)*10) = 0.

I understand why but I thought TB was better than that.

Roger

Thanks, Roger. You just sent MY cpu into a tail spin...

Well, we all know that 1 + 1 = 10, right? Smile

Brian


RE: Life's little surprises - Skywise - 12-31-2013

(12-30-2013, 10:34 PM)Skywise Wrote:
(12-30-2013, 04:26 PM)Roger Hunter Wrote: TB just told me that int((6.3-6.2)*10) = 0.

I understand why but I thought TB was better than that.

Roger

Thanks, Roger. You just sent MY cpu into a tail spin...

Well, we all know that 1 + 1 = 10, right? Smile

Brian

To expand, for those who may be reading, it all has to do with the way non-integer numbers are stored in computer memory. It's a sort of rounding error. Computers only work in binary numbers - 1's or 0's.

It's similar to how you write out 1 divided by 3. The answer is .3333, approximately. Approximately because, in reality those 3's go on forever, a repeating decimal. In base 10 numbers, the numbers we use everyday, 1/3rd cannot be expressed precisely in decimal.

In binary (base 2) certain numbers also cannot be expressed precisely. For example, the numbers 6.3 and 6.2 that roger gives in his example cannot be stored precisely, and when the difference is taken the result is not precisely .1. In fact, it turns out to be just a hair under .1. Therefore, when it is multiplied by 10, it turns out to be just a hair under 1, instead of one precisely.

The INT function in programming means to take the integer of the number, chopping off the decimals. Since the result is not precisely 1, but something just less than 1, all the decimals get chopped off and we are left with zero.

Now, something I discovered in C++ is that I can get the right answer if I program the equation differently.

int((6.3-6.2)*10) gives the answer 0, whereas
int((6.3f-6.2f)*10) gives the expected answer of 1.

That extra 'f' in there tells the compiler to treat the number as an 80bit extended floating point literal instead of the usual standard 64bit double precision floating point. Basically, I'm just using more decimals of precision even though it's still not exactly precise, so that when the answer is rounded off to 'only' 64bit, it rounds off to the exact value.

When you learn to program computers, you have to learn numbers and counting all over again.

Brian


RE: Life's little surprises - Roger Hunter - 12-31-2013

Quote:The INT function in programming means to take the integer of the number, chopping off the decimals. Since the result is not precisely 1, but something just less than 1, all the decimals get chopped off and we are left with zero.

Quite correct.

Quote:Now, something I discovered in C++ is that I can get the right answer if I program the equation differently.

int((6.3-6.2)*10) gives the answer 0, whereas
int((6.3f-6.2f)*10) gives the expected answer of 1.

That extra 'f' in there tells the compiler to treat the number as an 80bit extended floating point literal instead of the usual standard 64bit double precision floating point. Basically, I'm just using more decimals of precision even though it's still not exactly precise, so that when the answer is rounded off to 'only' 64bit, it rounds off to the exact value.

Since I'm programming in TrueBasic I don't have that "f" option so I did it this way;

fmag = 62
mag = 6.3
imag = mag*10
n = int(imag-fmag)

So n = 1

Quote:When you learn to program computers, you have to learn numbers and counting all over again.

Oh yes!

Roger


RE: Life's little surprises - Skywise - 12-31-2013

[quote='Roger Hunter' pid='36' dateline='1388459292']
Since I'm programming in TrueBasic I don't have that "f" option so I did it this way;

fmag = 62
mag = 6.3
imag = mag*10
n = int(imag-fmag)

So n = 1

[quote]

Yep. How you implement a calculation can affect the outcome when precision is involved. This can be a particular issue in strongly typed languages such as XB or C/C++ where commands which mix data types have an implied type conversion.

You may not have explicit types in TB, but TB has to translate things into code the CPU can use, and the CPU *does* have explicit types.

Most of the time it's not a issue and small errors won't affect the outcome, or are acceptable. Obviously you found an exception.

But your solution technically isn't the same calculation. You changed one of the input values from 6.2 to 62 and rearranged the formula to compensate.

I was able to implement code that assigned the numbers to variables, and then used those variables in the calculation and got the expected result. But I was also playing around with data types to get it to work.

x# = 6.3
y# = 6.2
z = (x#-y#)*10
q = INT(z)

x# and y# are doubles (double precisions floating point). z is an integer (in this case, 32 bit signed). In the calculation there is an implicit type conversion of the result of the calculation into an integer because I'm assigning the answer to z which is an integer, which rounded off the floating point result.

Of course, if I do,

q = INT((x#-y#)*10)

I get the 'wrong' answer.

What I did in the first case with multiple lines of code would be equivalent to,

q = INT(SLONG((x#-y#)*10)))

SLONG converts to a signed long integer.

Not sure if you can easily see what's happening with so much nesting.

Brian


RE: Life's little surprises - Roger Hunter - 12-31-2013

(12-31-2013, 04:09 AM)Skywise Wrote: Yep. How you implement a calculation can affect the outcome when precision is involved. This can be a particular issue in strongly typed languages such as XB or C/C++ where commands which mix data types have an implied type conversion.

You may not have explicit types in TB, but TB has to translate things into code the CPU can use, and the CPU *does* have explicit types.

Undoubtedly but TB has no way to use them.

Quote:But your solution technically isn't the same calculation. You changed one of the input values from 6.2 to 62 and rearranged the formula to compensate.

That's correct. I was computing an array index and floating point will get you into trouble there.

Quote:x# = 6.3
y# = 6.2
z = (x#-y#)*10
q = INT(z)

x# and y# are doubles (double precisions floating point). z is an integer (in this case, 32 bit signed). In the calculation there is an implicit type conversion of the result of the calculation into an integer because I'm assigning the answer to z which is an integer, which rounded off the floating point result.

Everything in TB is double precision real. I dislike types; it's extra work the PC should do for me. In QL SuperBasic you could say 2+two and get 4

Roger


RE: Life's little surprises - Skywise - 12-31-2013

(12-31-2013, 04:55 AM)Roger Hunter Wrote:
(12-31-2013, 04:09 AM)Skywise Wrote: You may not have explicit types in TB, but TB has to translate things into code the CPU can use, and the CPU *does* have explicit types.

Undoubtedly but TB has no way to use them.

Probably more like TB doesn't let the programmer use them.


(12-31-2013, 04:55 AM)Roger Hunter Wrote:
(12-31-2013, 04:09 AM)Skywise Wrote: But your solution technically isn't the same calculation. You changed one of the input values from 6.2 to 62 and rearranged the formula to compensate.

That's correct. I was computing an array index and floating point will get you into trouble there.

I can't have Array[3.14]?? Bummer. Tongue



Quote:Everything in TB is double precision real. I dislike types; it's extra work the PC should do for me. In QL SuperBasic you could say 2+two and get 4

It took me some time to get used to types, but I've been doing it that way for 12+ years now. Now it's even more important in C/C++.

In the end, whatever works. It's like the not quite sarcastic answer when someone asks, "What's the best telescope to buy?" "The one you'll use."

If PERL works for EQF, that's great. You like TB, and maybe FORTRAN? I like(d) XB, and now I'm getting the feel for C++.

BTW, I sent you an email with a sample program a couple days ago. Lemme guess... gmail didn't like the attachment and you didn't see it. Sad

Brian


RE: Life's little surprises - Roger Hunter - 12-31-2013

(12-31-2013, 04:09 AM)Skywise Wrote: Probably more like TB doesn't let the programmer use them.

Yeah. Sorta amounts to the same thing.

Quote:In the end, whatever works. It's like the not quite sarcastic answer when someone asks, "What's the best telescope to buy?" "The one you'll use."

Yes. I wanted and got a 3" reflector. It came with a tripod mount so I built an equatorial but made it too tall. Once I remade it the right height it wouldn't hold a setting. Needed thumbscrews in the joints and I had no taps and dies.

Now it's in my storage shed and there's not enough visible sky here to bother with it.

Quote:If PERL works for EQF, that's great. You like TB, and maybe FORTRAN? I like(d) XB, and now I'm getting the feel for C++.

BTW, I sent you an email with a sample program a couple days ago. Lemme guess... gmail didn't like the attachment and you didn't see it. Sad

Nope. Try again. If zipped, rename to piz or something.

Roger