This question already has answers here:
Apparent F#/BCL floating point bug
(3 answers)
Closed 7 years ago.
Multiplying
(327.59 * 100.0)
produces a number less than 32759, why is that? And how can this be avoided?
With a modified pretty printer for the F# Interactive the numeric precision is shown fully.
fsi.AddPrinter( fun (x:float) -> sprintf "%26.16e" x)
(327.59 * 100.0)
// val it : float = 3.2758999999999996e+004
32759.0
// val it : float = 3.2759000000000000e+004
That's why
(327.59 * 100.0) < 32759.0 = true
Related
This question already has answers here:
Is floating point math broken?
(31 answers)
Precision String Format Specifier In Swift
(31 answers)
Closed 6 years ago.
I have Double value is 7.92021 and I want to change it to 7.92 (Double type).
I was try 3 methods but all not worked!
Code 1:
let d1:Double = 7.92012
let d2 = Double(String(format: ".2f", d1))
// the result d2 = 7.92000000000002
Code 2:
let d1:Double = 7.92012
let value = NSDecimalNumber(double: d1)
value.decimalNumberByAdding(2)
let result = value.doubleValue
// the result = 7.92000000000002
Code 3:
let d1:Double = 7.92012
let d2 = round( d1 * 100 ) / 100
// d2 = 7.92000000000002
How I make the result value is 7.92 (double type)?
type Point<'t> =
val X : 't
val Y : 't
new(x : 't,y : 't) = { X = x; Y = y }
let clampedSubtract (p1:Point<_>) (p2:Point<_>) =
Point( max (p2.X - p1.X) 0, max (p2.Y - p1.Y) 0 )
If you look at the code above, you will notice, that the function is not implemented as generic as it should be.
First, using the 0 in the max expressions clamps the type to int. But it should be the type of whatever type Point<'t> has and not Point<int>.
But even more important, this function can only work as expected, if signed types are used for `t.
This raises a few questions of mine:
Is there a way to obtain the neutral element (zero) from a generic (number) type?
How can I express a restriction such as "only signed number"?
Is there a way to extend type constraint system in F#?
Thanks, in advance.
The solution to the first question as already answered is to use an inline function together with GenericZero and that's all.
Regarding the signed restriction, actually there's an easy way to restrict it to signed types. Use somewhere the generic unary negation which is defined only for signed types:
let inline clampedSubtract (p1:Point<_>) (p2:Point<_>) =
let zero = LanguagePrimitives.GenericZero
Point( max (p2.X + -p1.X) zero, max (p2.Y + -p1.Y) zero )
let result1 = clampedSubtract (Point(4 , 5 )) (Point(4 , 5 ))
let result2 = clampedSubtract (Point(4y , 5y )) (Point(4y , 5y ))
let result3 = clampedSubtract (Point(4uy, 5uy)) (Point(4uy, 5uy)) // doesn't compile
In general, if you want to restrict any generic function to signed types you can define this function:
let inline whenSigned x = ignore (-x)
let inline clampedSubtract (p1:Point<_>) (p2:Point<_>) =
whenSigned p1.X
let zero = LanguagePrimitives.GenericZero
Point( max (p2.X - p1.X) zero, max (p2.Y - p1.Y) zero )
Finally regarding your third question it's not very clear to me what do you mean with extending the type system. You can create static constraints by yourself, in that sense the system is already extensible.
I did a project sometime ago to emulate some Haskell types, part of the code of that project is still in a module in FsControl there you can have an idea to what level you can play with those constraints.
This makes it generic:
let inline clampedSubtract (p1:Point<_>) (p2:Point<_>) =
let zero = LanguagePrimitives.GenericZero
Point( max (p2.X - p1.X) zero, max (p2.Y - p1.Y) zero )
But there's no way to constrain it to signed primitive types.
This question already has answers here:
Why is Lua arithmetic is not equal to itself? [duplicate]
(1 answer)
What is a simple example of floating point/rounding error?
(9 answers)
Closed 9 years ago.
Why is 57.5 not same as 57.5? For example:
> b = 57.5
> print (57.5 == b)
true
> c = 0.575 * 100
> print (c)
57.5
> print (c == b)
false
> print (c, b)
57.5 57.5
So somehow even though both c and b is 57.5, the numbers are not equal
Is there perhaps a rounding issue? but shouldn't the numbers print differently if that's so?
Edit:
Excellent, is there a way to print the actual value in LUA? Like if I want it to print 57.4999999999...?
b=57.499999999999996
c = 0.575 * 100
print (c==b)
This will return True.
Actually, If you enter .575
"%.17f" % 0.575
it returns 0.57499999999999996.
It's the same reason (1/3) * 3 won't give you the same result as 1 in fixed-precision decimal arithmetic. There is no representation that can be multiplied by 3 to give 1 in fixed-precision decimal.
They print the same because the printing code rounds the output. Would you want (1/3) * 3 to print as .999999999999999 or 1?
Try this:
b = 57.5
c = 0.575 * 100
print (string.format("b = %.24f", b))
print (string.format("c = %.24f", c))
Output is:
b = 57.500000000000000000000000
c = 57.499999999999992894572642
In response to your edited question of how to print the number with greater precision, it's roughly the same as it is in C with printf.
> =string.format('%.17f', 0.1)
0.10000000000000001
Please see this question as well.
As for the issues relating to floating point numbers, they've been covered numerous times in the past in other places. There's an informative link given in the comments that I'll copy here.
I tried to get the cube root in F#. But here is my problem.
let x5 = ((float 64) ** (1.0/3.0));;
val x5 : float = 4.0
int x5;; //expected 4
val it : int = 3
The result should be 4, not 3.
What's wrong?
Nothing is wrong, the thing is that the value of your x5 is a bit less, than 4.0.
You may explicitly see how much less using fsi:
let x5 = ((float 64) ** (1.0/3.0))
let err = 4.0 - x5;;
val x5 : float = 4.0
val err : float = 4.440892099e-16
It looks like you may be looking at the wrong variable.
I checked it myself and an example is here:
http://ideone.com/kn9jd
(ideone is a free online compilation/execution service.)
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
What is a simple example of floating point/rounding error?
When I execute the following Lua code:
a = 5.6
b = 14 * 0.4
c = 11.2 / 2
d = 28 * 0.2
print( a == b )
print( a == c )
print( a == d )
print( b == c )
print( b == d )
print( c == d )
I get the following results:
false
true
false
false
true
false
Can someone explain why 14 * 0.4 and 28 * 0.2 are not equal to 5.6?
Thanks
You are dealing with the natural imprecision of binary floating point numbers. Your number a might be 5.5999999999999996 and your result b might be 5.6000000000000005, which are not equal.
In fact, here is the same calculation as done by Python:
>>> 5.6
5.5999999999999996
>>> 14 * 0.4
5.6000000000000005
This behaviour is common to all implementations of binary floating point numbers.