Roku Developer Program

Developers and content creators—a complete solution for growing an audience directly.
cancel
Showing results for 
Search instead for 
Did you mean: 
greubel
Level 7

Why does this fail ?

I'm getting the wrong results on all box platforms.

x = Log(8192.0)/Log(2)
? "x = " Type(x) " " x
y = Int( x )
? "y = " Type(y) " " y

Int does round but on a whole number and down ?

x = Float 13
y = Integer 12
0 Kudos
16 Replies
RokuMarkn
Level 7

Re: Why does this fail ?

The result of the divide is a little less than 13, which rounds down to 12 when you convert to integer. It still prints as 13 as a float since its so close to 13. The same thing happens in C:


float a = log(8192.0);
float b = log(2.0);
float x = a / b;
int y = x;
printf("%g %d\n", x, y);


If you printf x in %A format, it's 0X1.9FFFFEP+3 while a real 13 is 0X1.AP+3.

--Mark
0 Kudos
greubel
Level 7

Re: Why does this fail ?

So we never know which way int() is going to round ?
In this case, it should have been up ????
0 Kudos
RokuMarkn
Level 7

Re: Why does this fail ?

Int always rounds down. The problem is the number you are rounding is close to but a little less than 13.

--Mark
0 Kudos
RokuMarkn
Level 7

Re: Why does this fail ?

Of course if you want to round to the nearest integer rather than rounding down, you can say

y = Int(x + 0.5)


--Mark
0 Kudos
greubel
Level 7

Re: Why does this fail ?

That sometimes throughs the answer off.
I though that fix(x) was supposed to do that, but it doesn't work either.
There should be an exact way to do it. Either round down or round up or just chop it off.
What I'm looking for is the exponent (power of 2) of a real number as an integer.
0 Kudos
RokuMarkn
Level 7

Re: Why does this fail ?

I'm not sure you're understanding that the problem has nothing to do with the int conversion, it's due to the loss of precision in the log and divide operations. If you've ever taken a Numerical Analysis course, you may recall the many dangers of working with floating point numbers. In general, what you want to do is impossible for arbitrary real numbers; for example, 2^70 and (2^70)-1 are both represented by the same floating point number, so there's no way to tell that log2 of the first is 70 while log2 of the second is 69.

I would probably use something like this. It's rather ugly (and untested) but it should be more accurate than using logs.

function Log2(x as Double) as Integer
lg = 0
val = 1.0
while x > val
lg = lg + 1
val = val * 2
end while
return lg
end function


--Mark
0 Kudos
EnTerr
Level 8

Re: Why does this fail ?

Well, hm. Python has the same precision limitations, how come it works there?
>>> from math import log
>>> 0.1 + 0.2
0.30000000000000004
>>> 2.**70, 2.**70 - 1
(1.1805916207174113e+21, 1.1805916207174113e+21)
>>> 2.**70 == 2.**70 - 1
True
>>> log(8192) / log(2)
13.0
>>> log(8192) / log(2) == 13
True
0 Kudos
greubel
Level 7

Re: Why does this fail ?

This appears to work for + and - floats with + and - exponents.
What I'm trying to do is to pack / unpack a "binary" real number from / to a roByteArray.
The float is done, at least it's been running for an hour, feeding the routines random values.
Now for the double.
*
function Log2(x as object) as Integer

if Sgn(x) < 0
x = x * -1.0
end if
lg = 0
val = 1.0
if val < x
while x > val
lg = lg + 1
val = val * 2
end while
lg = lg -1
elseif val > x
while x < val
lg = lg - 1
val = val / 2
end while
end if
return lg

end function
0 Kudos
EnTerr
Level 8

Re: Why does this fail ?

Do you really need log2 function as such?
I am asking because you are already building the mantissa (significand?) while calculating the exponent part. Intuitively feels to me the process is:

sign = sgn(x)
x = abs(x)
exp = 0
while x >= 2: x = x / 2: exp = exp - 1: end while
while x < 1: x = x * 2: exp = exp + 1 : end while
mant = int((x - 1) * 2^23 + 0.5)
0 Kudos