tips from a demo coder
tips from a demo coder
this guy gives an interesting talk
https://www.youtube.com/watch?v=h4MS5zU_C0c
https://www.youtube.com/watch?v=h4MS5zU_C0c
Last edited by dafhi on Dec 27, 2017 6:38, edited 2 times in total.
Re: tips from a java demo coder
He is not talking about java, but javascript. As for the stuff about floating point, which part are you talking about specifically?
Re: tips from a demo coder
Oh, yeah. I was not sure if you were talking about that or the pi approximations. That is very true. There are certain values that are impossible to store accurately as a floating point number because they will always be off by one digit at the end of the precision. It is because of the IEEE standard for encoding decimals that basically everything uses.
There are some numbers (can't remember which right now) that you can run this code and it will fail:
I don't think 10 is one of those numbers, but there are several. I will look it up later and give a real working example.
As a side not, the point of the pi approximations is to reduce the size of the javascript code. I don't THINK that would translate to smaller exe in a compiled language, but I have not tested. My gut says there would be no notable difference.
There are some numbers (can't remember which right now) that you can run this code and it will fail:
Code: Select all
Dim as single x = 10, y = 10
if x = y then
Print "Equal"
end if
As a side not, the point of the pi approximations is to reduce the size of the javascript code. I don't THINK that would translate to smaller exe in a compiled language, but I have not tested. My gut says there would be no notable difference.
Re: tips from a demo coder
Code: Select all
Dim as single x = .1, y = .1 * .1 * .1
if x * x * x = y then
Print "Equal"
else
print "not equal: ";x * x * x, y
?
? .1 * .1 * .1, x * x * x, x * x * .1
end if
Re: tips from a demo coder
Yes, exactly.sancho3 wrote:Code: Select all
Dim as single x = .1, y = .1 * .1 * .1 if x * x * x = y then Print "Equal" else print "not equal: ";x * x * x, y ? ? .1 * .1 * .1, x * x * x, x * x * .1 end if
Re: tips from a demo coder
If you're comparing two floating point numbers for equality, you probably have a bug in your code.
...I had to fix such a bug in my own code just last night :/
...I had to fix such a bug in my own code just last night :/
Re: tips from a demo coder
Only combinations of 1/2, 1/4, 1/8, 1/16, etc can be represented precisely with binary, up to the limit of the significant digits in the IEEE format you are using. Many common decimal fractions end up being infinitely-repeating sequences in binary. For example, if my binary division skills are working:Imortis wrote:I don't think 10 is one of those numbers, but there are several. I will look it up later and give a real working example.
0.1 = 0.000110011001
0.2 = 0.00110011001
0.3 = 0.010011001
0.4 = 0.0110011001
But others are exact:
0.5 = 0.1
Re: tips from a demo coder
Yeah, comparing two floating point numbers for equality is tricky (if not even incorrect). Typical workaround:
Code: Select all
function cmpf( byref a as single, byref b as single, byval epsilon as single = 0.00000001 ) as boolean
return( abs( a - b ) < epsilon )
end function
dim as single x = .1, y = .1 * .1 * .1
if( cmpf( x * x * x, y ) = true ) then
? "Equal"
else
? "not equal: "; x * x * x, y
?
? .1 * .1 * .1, x * x * x, x * x * .1
end if
? .1 * .1 * .1, x * x * x, x * x * .1
sleep()
Re: tips from a demo coder
there's one more layer of magic peeled away from my perception of fpu logic :-)caseih wrote: Only combinations of 1/2, 1/4, 1/8, 1/16, etc can be represented precisely with binary, up to the limit of the significant digits in the IEEE format you are using. Many common decimal fractions end up being infinitely-repeating sequences in binary. For example, if my binary division skills are working:
0.1 = 0.000110011001
0.2 = 0.00110011001
0.3 = 0.010011001
0.4 = 0.0110011001
But others are exact:
0.5 = 0.1
Re: tips from a demo coder
Remember expanded notation for numbers?dafhi wrote:there's one more layer of magic peeled away from my perception of fpu logic :-)
142.342 = 1*10^2 + 4*10 +2 + 3*10^-1 + 4*10^-2 + 2*10^-3.
Binary works the same way:
142.342 = 10001110.0101011110001101... = 1*2^7 + 1*2^3 + 1*2^2 + 1*2^1 + 1*2^-2 + 1*2^-4 etc
Same for all bases. In IEEE floating point, basically all numbers are stored in a form like this:
sign*0.xxxxxxxxx * 2^exponent where xxxxxx is the binary rational. The leading zero is assumed and not stored.
Re: tips from a demo coder
It can be done if you specify a degree of precision, a tolerable delta, whatever. But I agree it's tricky - we had over a dozen threads in the Masm32 forum, for example: FPU compare real to integer problempaul doe wrote:Yeah, comparing two floating point numbers for equality is tricky (if not even incorrect).
Re: tips from a demo coder
Of course, that's what the 'epsilon' parameter of the code above is for. Over the years, as compilers improved and I got fed up, I slowly ported all of my ASM to HLL. This, for example, was a function I used a lot:jj2007 wrote:It can be done if you specify a degree of precision, a tolerable delta, whatever.
Code: Select all
function fmod( byval lhs as single, byval rhs as single ) as single
' Computes the floating point remainder ( modulus division ) of two floating point numbers
asm
fld dword ptr [ rhs ] ' Load dividend
fld dword ptr [ lhs ] ' Load modulus
fprem ' Performs the float division and load the remainder in st( 0 )
fstp dword ptr [ function ] ' Loads the content of st( 0 ) into function result
' Set the flags of the floating point registers to empty
ffree st( 0 )
ffree st( 1 )
' Pops the stack
fincstp
fincstp
end asm
end function
Code: Select all
'' portable floating-point mod function
#ifndef fmod
#define fmod( numer, denom ) numer - int( numer / denom ) * denom
#endif
Re: tips from a demo coder
I'm not sure if there are standard, portable values for epsilon. But I've read some things that recommend these values:
single precision: 1E-5
double precision: 1E-9
long double precision: 1E-9
single precision: 1E-5
double precision: 1E-9
long double precision: 1E-9
Re: tips from a demo coder
Looks a bit too fixed and hand-crafted for my taste. Fcmp, for example, does it automatically for large ranges, and you can tell it do it with lo, medium, hi or top precision. Note the figures are 60 orders of magnitude apart and differ only in the last digit:paul doe wrote:Of course, that's what the 'epsilon' parameter of the code above is for.
Code: Select all
SetGlobals REAL10 MyPI=3.141592653589793238, hiPI=3.141592653589793239, loPI=3.141592653589793237
SetGlobals REAL10 MyPI30=3.141592653589793238e30, hiPI30=3.141592653589793239e30, loPI30=3.141592653589793237e30
SetGlobals REAL10 MyPIm30=3.141592653589793238e-30, hiPIm30=3.141592653589793239e-30, loPIm30=3.141592653589793237e-30