Integer question : Int( NUMBER )

Could someone help me with this very basic question about Int() please ?

Refering to http://www.amibroker.com/guide/afl/int.html
and code

a = 0.59 ;
Plot( 100*a ,"before int",colorblue);
Plot( int(100*a) ,"after int",colorred);

L38 AFL int

I was expecting to see same value 59 from both calculation
but it did not, per picture.
This does not always happen, e.g.
0.57, 0.58 are OK but 0.59 becomes issue per picture, and so on.

Int() TRUNCATES fractional part. Normal Plot will round to certain number of digits. Now 0.59 has infinite representation in binary that is slightly less than 0.59. Check this: IEEE-754 Floating Point Converter (IEEE754 floating point representation is 0x3f170a3d which is really 0.589999973773956298828125)

You need to read this to understand:

1 Like

Thank you Tomasz.

So I feel it is error prone and better to avoid using int(number)
due to int is supposed to used with fraction, but user never knows
that his CPU sees most fraction numbers different from he thinks.

In case I want to check whether a number has
the third or fourth decimal digit,
code below could not serve my purpose (due to binary decimal number issue).

has_third_decimal_digit = 100*C-Int(100*C) > 0;

Could you help point out how to get around to check this condition correctly please ?
Thank you.

Re-read the article until you understand, because right now it is obvious that you didn't.
It is not about CPU. It is about finite precision math in given base. Computers use BINARY system (not decimal). 0.01 in binary system is infinite fraction, like 1/3 is infinite in decimal system.
The same way as 3 * 0.33333333 (1/3 in decimal system) is not 1,
you should not expect that you will get exact integer each time you use 100*C.

2 Likes

Because I can not expect that I will get exact integer each time I use 100*C,
so it seems there is no way to check what I want by using only int()
no matter what software I use.

I will try to get around this by myself.
Thank you for your time.

You can use round() for that purpose

SamL - really please DO READ the responses carefully. I wrote you that Int() TRUNCATES fractional part as instructed in the guide. What you really are after is NOT truncation but ROUNDING to nearest integer. You use Round() function for your intended purpose AFL Function Reference - ROUND

1 Like

Thank you very much Tomasz :yellow_heart: , and Armin.

Further observation : not only 0.59 that has binary stored in float slightly less than .59 but .57 & .58 are also less. Yet only .59 has issue with int()
0.57 => 0.569999992847442626953125...
0.58 => 0.579999983310699462890625...
0.59 => 0.589999973773956298828125...
L39 int round

When using round() instead of int(),
the unwanted results disappeared about half which is improvement. Thank you.
So round() solved about half of the unwanted results.

I guess most (but not all) fraction numbers in decimal system
has endless fraction in binary system.
So it may be about how and when a fraction number will be rounded in CPU
that makes the different, e.g. 0.59 in above example and example below.

L40 int round

Your recommended link about floating point arithmetic and IEEE754
are difficult to fully understand for me T_T.

Still thinking either to get around, or quit.
Hope this is useful observation for people who have same question like me. :blush:
Thank you.

ROUND() allows to do what you intent to do, which is detecting whether a number has decimal digits or not. But you need to apply it correctly. You may need to multiply by a bigger number (x1000 i.e.) before round()

example: 18.001 does it have a third decimal digit?

1000x18.001 - 1000*round(18.001) = 18001 - 18000 = 1 > 0 --> YES

Do your math correctly, you only need Round() for your purposes

Thanks

1 Like

Jeez... did you even bother to READ what was written previously? RE-READ it ten or maybe more times until it sinks in. Just read and read and read until you get that simple thing that 0.01 is not finite fraction in binary system. This applies to pretty much all multiplies of 0.01 with exception of negative powers of 2.

As to the SOLUTION, you should not truncate fractional part but ROUND.
It also has been told to you dozens of times already.

Just use Round() function instead

1 Like