RE: Math weirdness

2011-02-04 Thread Mark A. Kruger

Mike,

I don't think there's any JVM args to do this, but there are properties of
some of the math objects that seem to be able to do this. But there are also
half a million posts on how to work around this problem in Java (ha). Kudos
for an excellent explanation of floating point precision problems... nicely
done!

-Mark


Mark A. Kruger, MCSE, CFG
(402) 408-3733 ext 105
Skype: markakruger
www.cfwebtools.com
www.coldfusionmuse.com
www.necfug.com



-Original Message-
From: Mike Chabot [mailto:mcha...@gmail.com] 
Sent: Thursday, February 03, 2011 6:24 PM
To: cf-talk
Subject: Re: Math weirdness


Jen,
This quirk is due to the difference between exact integer math and
approximate floating point math. Some imprecision is introduced when CF
converts the decimal number that you see to a binary floating point number
that the computer performs the math function on. Some decimal numbers cannot
be exactly represented by binary floating point numbers, so floating point
math often has unexpected results. If you find this idea confusing, think of
the more familiar base-10 number of 1/3. It looks exact in that
representation, but presented another way that number is actually
0.33...(repeating). Infinitely repeating numbers also exist when
using base-2 binary instead of base-10, but with a different set of
fractions that cannot be represented without a loss of precision, such as
0.1. Computers cannot handle infinitely repeating numbers, so some rounding
and loss of precision occurs. You should never see the precision problem
with common integer math like incrementing loop counters.

This floating point precision behavior impacts most programming languages,
not just ColdFusion and Java. In strongly-typed platforms, such as .NET and
SQL Server, you can tell the complier that a number is a decimal and that
you want math performed on that number to be precise fixed-point math, not
imprecise floating point math. I'm not sure of any good way to pull this off
in ColdFusion. Possibly something with the javacast function would work, but
that would be messy code. I just use a rounding function.

The question of why does ColdFusion use imprecise floating point math
instead of exact fixed-point math is one I don't have the answer to without
researching it.

It is annoying to have pass all math involving decimals through a rounding
function, and it is easy to forget to do this. Does anyone know of a good
way to fix this problem on a site-wide basis?

It would be nice if ColdFusion was smart enough to know that addition and
subtraction involving base-10 numbers with only one decimal point cannot
result in a number with greater than one decimal point of precision.

#3.2 - 3.2 + 8 - 8# = 0
#3.2 + 8 - 3.2 - 8# = -8.881784197E-016
#0.6/0.2# = 3
#0.6/0.2 - 3# = -4.4408920985E-016

-Mike Chabot

On Thu, Feb 3, 2011 at 3:56 PM, Jen McVicker snarkmeis...@gmail.com wrote:


 OK, a coworker sent this over to me and I am puzzled:



 cfset number1 = evaluate(12.5 * 1.1)

 cfset number2 = 12.5 * 1.1

 cfset number3 = 13.75

 cfset testEval = number3 - number1

 cfset testNoEval = number3 - number2



 cfoutput

 number1 (12.5 * 1.1): strong#number1#/strongbr

 number2 (#number2#): strong#number2#/strongbr

 number3 (#number3#): strong#number3#/strongbr

 #number3# - #number1#: strong#testEval#/strongBR

 #number3# - #number2#: strong#testNoEval#/strongBR

 cfif number3 eq number1Number3 equals number1BR

 cfelseNumber3 does NOT equal number1BR/cfif

 cfif number3 eq number2Number3 equals number2BR

 cfelseNumber3 does NOT equal number2BR/cfif

 /cfoutput



 Results in:


 number1 (evaluate(12.5 * 1.1)): 13.75
 number2 (12.5 * 1.1): 13.75
 number3 (13.75): 13.75
 13.75 - 13.75: 0
 13.75 - 13.75: -1.7763568394E-015
 Number3 equals number1
 Number3 does NOT equal number2



 Obviously number2 is set to a reference of the expression rather than the
 actual value that is returned.  But since the variable outputs as 13.75,
 why
 does it make a difference?  Can someone explain it to me in small words so
 that I will understand?  ;-)



 Jen Perkins McVicker
 Adobe Certified ColdFusion Developer
 Email: jen.mcvic...@gmail.com

 Linked In: http://www.linkedin.com/in/jmcvicker





 



~|
Order the Adobe Coldfusion Anthology now!
http://www.amazon.com/Adobe-Coldfusion-Anthology/dp/1430272155/?tag=houseoffusion
Archive: 
http://www.houseoffusion.com/groups/cf-talk/message.cfm/messageid:341859
Subscription: http://www.houseoffusion.com/groups/cf-talk/subscribe.cfm
Unsubscribe: http://www.houseoffusion.com/groups/cf-talk/unsubscribe.cfm


re: Math weirdness

2011-02-03 Thread Jason Fisher

Whoa, creepy.  That is certainly very odd.



From: Jen McVicker snarkmeis...@gmail.com
Sent: Thursday, February 03, 2011 3:57 PM
To: cf-talk cf-talk@houseoffusion.com
Subject: Math weirdness

OK, a coworker sent this over to me and I am puzzled:

cfset number1 = evaluate(12.5 * 1.1)

cfset number2 = 12.5 * 1.1

cfset number3 = 13.75

cfset testEval = number3 - number1

cfset testNoEval = number3 - number2

cfoutput

number1 (12.5 * 1.1): strong#number1#/strongbr

number2 (#number2#): strong#number2#/strongbr

number3 (#number3#): strong#number3#/strongbr

#number3# - #number1#: strong#testEval#/strongBR

#number3# - #number2#: strong#testNoEval#/strongBR

cfif number3 eq number1Number3 equals number1BR

cfelseNumber3 does NOT equal number1BR/cfif

cfif number3 eq number2Number3 equals number2BR

cfelseNumber3 does NOT equal number2BR/cfif

/cfoutput

Results in:

number1 (evaluate(12.5 * 1.1)): 13.75
number2 (12.5 * 1.1): 13.75
number3 (13.75): 13.75
13.75 - 13.75: 0
13.75 - 13.75: -1.7763568394E-015
Number3 equals number1
Number3 does NOT equal number2

Obviously number2 is set to a reference of the expression rather than the
actual value that is returned.  But since the variable outputs as 13.75, 
why
does it make a difference?  Can someone explain it to me in small words so
that I will understand?  ;-)  

Jen Perkins McVicker
Adobe Certified ColdFusion Developer
Email: jen.mcvic...@gmail.com

Linked In: http://www.linkedin.com/in/jmcvicker



~|
Order the Adobe Coldfusion Anthology now!
http://www.amazon.com/Adobe-Coldfusion-Anthology/dp/1430272155/?tag=houseoffusion
Archive: 
http://www.houseoffusion.com/groups/cf-talk/message.cfm/messageid:341851
Subscription: http://www.houseoffusion.com/groups/cf-talk/subscribe.cfm
Unsubscribe: http://www.houseoffusion.com/groups/cf-talk/unsubscribe.cfm


Re: Math weirdness

2011-02-03 Thread Ian Skinner

On 2/3/2011 12:56 PM, Jen McVicker wrote:
 Can someone explain it to me in small words so
 that I will understand?  ;-)

Computers do not understand decimal (base 10) numbers.  They only truly 
understand binary (base 2) numbers.  Sometimes when converting back and 
forth between the base 10 numbers we humans like to use and the base 2 
numbers that computers have to use, small differences in rounding occur.

99.9% of the time, the computer systems handle these and we humans can 
ignore the base 2 nature of computers.  But sometimes we really must be 
computer programmers and understand the real world of binary computers.




~|
Order the Adobe Coldfusion Anthology now!
http://www.amazon.com/Adobe-Coldfusion-Anthology/dp/1430272155/?tag=houseoffusion
Archive: 
http://www.houseoffusion.com/groups/cf-talk/message.cfm/messageid:341852
Subscription: http://www.houseoffusion.com/groups/cf-talk/subscribe.cfm
Unsubscribe: http://www.houseoffusion.com/groups/cf-talk/unsubscribe.cfm


Re: Math weirdness

2011-02-03 Thread rex

These are the pitfalls of a dynamically typed language, and FLOAT/INT 
conversions.

Your number1 is a string, number2 is a Double, and your number 3 is a 
string:

cfoutput
number3 is #number3.getClass().getName()#br /
number2 is #number2.getClass().getName()#br /
number1 is #number1.getClass().getName()#br /
/cfoutput

If you do val() they will equal out:

cfif val(number3) eq val(number2)Number3 equals number2BR
cfelseNumber3 does NOT equal number2BR/cfif

 From http://docs.sun.com/source/806-3568/ncg_goldberg.html#680, the 
result of a floating-point calculation must often be rounded in order to 
fit back into its finite representation. This rounding error is the 
characteristic feature of floating-point computation.

Checkout this code:

cfoutput
 #(0.1 * 0.1) EQ 0.01# !--- not equal! ---
 #0.1 * 0.1# !--- 0.1 multiplied by 0.1 is actually 0.01, so 
why aren't they equal? ---
 #javacast(bigDecimal, 0.1 * 0.1)# !--- results in 
0.010002 ---
/cfoutput

If you need strict computation, stick to Doubles or bigDecimals all the 
time, and don't rely on implicit conversions.

Also this is not a CF thing or a Java thing, other languages plague this 
too i.e Python (for division, 3/4 is different from 3.0/4.0) and .NET 
(http://stefanoricciardi.com/2010/03/02/comparing-floating-point-numbers/), 
and PHP 
(http://it.slashdot.org/story/11/01/06/1820208/PHP-Floating-Point-Bug-Crashes-Servers
 
http://it.slashdot.org/story/11/01/06/1820208/PHP-Floating-Point-Bug-Crashes-Servers?from=rss
 
or just start typing in google instant, php floating... and you'll see 
all the suggestions hehe)

On 2/3/2011 12:56 PM, Jen McVicker wrote:
 number1 (evaluate(12.5 * 1.1)): 13.75
 number2 (12.5 * 1.1): 13.75
 number3 (13.75): 13.75
 13.75 - 13.75: 0
 13.75 - 13.75: -1.7763568394E-015
 Number3 equals number1
 Number3 does NOT equal number2



 Obviously number2 is set to a reference of the expression rather than the
 actual value that is returned.  But since the variable outputs as 13.75, why
 does it make a difference?  Can someone explain it to me in small words so
 that I will understand?  ;-)



 Jen Perkins McVicker
 Adobe Certified ColdFusion Developer
 Email: jen.mcvic...@gmail.com

 Linked In: http://www.linkedin.com/in/jmcvicker





 

~|
Order the Adobe Coldfusion Anthology now!
http://www.amazon.com/Adobe-Coldfusion-Anthology/dp/1430272155/?tag=houseoffusion
Archive: 
http://www.houseoffusion.com/groups/cf-talk/message.cfm/messageid:341853
Subscription: http://www.houseoffusion.com/groups/cf-talk/subscribe.cfm
Unsubscribe: http://www.houseoffusion.com/groups/cf-talk/unsubscribe.cfm


Re: Math weirdness

2011-02-03 Thread Mike Chabot

Jen,
This quirk is due to the difference between exact integer math and
approximate floating point math. Some imprecision is introduced when CF
converts the decimal number that you see to a binary floating point number
that the computer performs the math function on. Some decimal numbers cannot
be exactly represented by binary floating point numbers, so floating point
math often has unexpected results. If you find this idea confusing, think of
the more familiar base-10 number of 1/3. It looks exact in that
representation, but presented another way that number is actually
0.33...(repeating). Infinitely repeating numbers also exist when
using base-2 binary instead of base-10, but with a different set of
fractions that cannot be represented without a loss of precision, such as
0.1. Computers cannot handle infinitely repeating numbers, so some rounding
and loss of precision occurs. You should never see the precision problem
with common integer math like incrementing loop counters.

This floating point precision behavior impacts most programming languages,
not just ColdFusion and Java. In strongly-typed platforms, such as .NET and
SQL Server, you can tell the complier that a number is a decimal and that
you want math performed on that number to be precise fixed-point math, not
imprecise floating point math. I'm not sure of any good way to pull this off
in ColdFusion. Possibly something with the javacast function would work, but
that would be messy code. I just use a rounding function.

The question of why does ColdFusion use imprecise floating point math
instead of exact fixed-point math is one I don't have the answer to without
researching it.

It is annoying to have pass all math involving decimals through a rounding
function, and it is easy to forget to do this. Does anyone know of a good
way to fix this problem on a site-wide basis?

It would be nice if ColdFusion was smart enough to know that addition and
subtraction involving base-10 numbers with only one decimal point cannot
result in a number with greater than one decimal point of precision.

#3.2 - 3.2 + 8 - 8# = 0
#3.2 + 8 - 3.2 - 8# = -8.881784197E-016
#0.6/0.2# = 3
#0.6/0.2 - 3# = -4.4408920985E-016

-Mike Chabot

On Thu, Feb 3, 2011 at 3:56 PM, Jen McVicker snarkmeis...@gmail.com wrote:


 OK, a coworker sent this over to me and I am puzzled:



 cfset number1 = evaluate(12.5 * 1.1)

 cfset number2 = 12.5 * 1.1

 cfset number3 = 13.75

 cfset testEval = number3 - number1

 cfset testNoEval = number3 - number2



 cfoutput

 number1 (12.5 * 1.1): strong#number1#/strongbr

 number2 (#number2#): strong#number2#/strongbr

 number3 (#number3#): strong#number3#/strongbr

 #number3# - #number1#: strong#testEval#/strongBR

 #number3# - #number2#: strong#testNoEval#/strongBR

 cfif number3 eq number1Number3 equals number1BR

 cfelseNumber3 does NOT equal number1BR/cfif

 cfif number3 eq number2Number3 equals number2BR

 cfelseNumber3 does NOT equal number2BR/cfif

 /cfoutput



 Results in:


 number1 (evaluate(12.5 * 1.1)): 13.75
 number2 (12.5 * 1.1): 13.75
 number3 (13.75): 13.75
 13.75 - 13.75: 0
 13.75 - 13.75: -1.7763568394E-015
 Number3 equals number1
 Number3 does NOT equal number2



 Obviously number2 is set to a reference of the expression rather than the
 actual value that is returned.  But since the variable outputs as 13.75,
 why
 does it make a difference?  Can someone explain it to me in small words so
 that I will understand?  ;-)



 Jen Perkins McVicker
 Adobe Certified ColdFusion Developer
 Email: jen.mcvic...@gmail.com

 Linked In: http://www.linkedin.com/in/jmcvicker





 

~|
Order the Adobe Coldfusion Anthology now!
http://www.amazon.com/Adobe-Coldfusion-Anthology/dp/1430272155/?tag=houseoffusion
Archive: 
http://www.houseoffusion.com/groups/cf-talk/message.cfm/messageid:341857
Subscription: http://www.houseoffusion.com/groups/cf-talk/subscribe.cfm
Unsubscribe: http://www.houseoffusion.com/groups/cf-talk/unsubscribe.cfm