Reputation: 39
So I start with : 9.638554216867471
I have this code :
{[x;noOfDigits]
x:string x;
if[null wIsDot:first ss[x;"."];:"F"$x];
noOfChars:min(noOfDigits + 1 + wIsDot;count x);
"F"$noOfChars#x
}
I expect to get this : 9.63
But I get : 9.630000000000001
"F"$"9.63" always gives 9.630000000000001
Upvotes: 0
Views: 418
Reputation: 1097
Simple ways to cast a float to a string:
q)q:9.638554216867471
q)string .01 xbar q / truncate
"9.63"
q)string .01*floor .5+100*q / round
"9.64"
Functional alternatives to your original:
q)ft:{[x;nd]string(10 xexp neg nd)xbar x} / truncate
q)ft[q;2]
"9.63"
q)fr:{[x;nd]string%[;s]floor .5+x*s:10 xexp nd} / round
q)fr[q;2]
"9.64"
Upvotes: 0
Reputation: 13657
There are various built-in functions you can use if the end goal is just to pretty-print numbers to specified decimal places:
q)update prettyPrint:-27!(2i;floats) from ([]floats:9.63 1.2345678)
floats prettyPrint
--------------------
9.63 "9.63"
1.234568 "1.23"
Other built-in functions are .Q.f
and .Q.fmt
but the newer -27!
might be preferable
Upvotes: 1
Reputation: 96
In kdb the final digit in a floating point number is notoriously unreliable, you can read about it here:
https://code.kx.com/q/basics/precision/
Just to give an idea, with \P set to 0 you get:
q)"F"$"9.63"
9.6300000000000008
q)9.63="F"$"9.63"
1b
So there is nothing wrong with your code, its just a quirk to be aware of.
Upvotes: 3