cancel
Showing results for 
Search instead for 
Did you mean: 

.Q.f output unexpected value in kdb4.0

BaiChen
New Contributor III

 

BaiChen_0-1695179415330.png

Hello all,

Came across a problem with .Q.f . 

We expected the first output to be 4194304.98 .  

I saw this issue only in kdb4.0. 

Output in kdb3.5 is expected. 

Any advice is appreciated. 

1 ACCEPTED SOLUTION

rocuinneagain
Valued Contributor
Valued Contributor
From 3.6 Readme
2018.09.26
NEW
added -27! as a more precise, builtin version of .Q.f. n.b. It is atomic and doesn't take \P into account. e.g.
 q)("123456789.457";"123456790.457")~-27!(3i;0 1+2#123456789.4567)
The definition of .Q.f changed at this time also - when comparing q.k file definitions:
3.6.0 2018.09.10
f:{$[^y;"";y<0;"-",f[x;-y];y<1;1_f[x;10+y];9e15>j:"j"$y*/x#10;(x_j),".",(x:-x)#j:$j;$y]}
3.6.0 2018.10.03
f:{$[^y;"";y<0;"-",f[x;-y];y<1;1_f[x;10+y];9e15>j:"j"$y*prd x#10f;(x_j),".",(x:-x)#j:$j;$y]}

 

 Floating point numbers are not exact and such behaviours should be expected in certain cases:

https://code.kx.com/q/basics/precision/

 

They are approximations:
q)\P 0
q)4194303.975
4194303.9750000001
q)4194304.975
4194304.9749999996

 

The same in C:
int main()
{
        double x = 4194303.975;
        printf("%10.10f\n",x);
}
Result:
4194303.9750000001

 

If you find that you need exact decimal rounding, consider whether you actually need to operate in fixed-point, rather than floating-point.
e.g. keep monetary values in integral millicents etc.

 

 

 

View solution in original post

1 REPLY 1

rocuinneagain
Valued Contributor
Valued Contributor
From 3.6 Readme
2018.09.26
NEW
added -27! as a more precise, builtin version of .Q.f. n.b. It is atomic and doesn't take \P into account. e.g.
 q)("123456789.457";"123456790.457")~-27!(3i;0 1+2#123456789.4567)
The definition of .Q.f changed at this time also - when comparing q.k file definitions:
3.6.0 2018.09.10
f:{$[^y;"";y<0;"-",f[x;-y];y<1;1_f[x;10+y];9e15>j:"j"$y*/x#10;(x_j),".",(x:-x)#j:$j;$y]}
3.6.0 2018.10.03
f:{$[^y;"";y<0;"-",f[x;-y];y<1;1_f[x;10+y];9e15>j:"j"$y*prd x#10f;(x_j),".",(x:-x)#j:$j;$y]}

 

 Floating point numbers are not exact and such behaviours should be expected in certain cases:

https://code.kx.com/q/basics/precision/

 

They are approximations:
q)\P 0
q)4194303.975
4194303.9750000001
q)4194304.975
4194304.9749999996

 

The same in C:
int main()
{
        double x = 4194303.975;
        printf("%10.10f\n",x);
}
Result:
4194303.9750000001

 

If you find that you need exact decimal rounding, consider whether you actually need to operate in fixed-point, rather than floating-point.
e.g. keep monetary values in integral millicents etc.