On 2017/07/11 3:51 AM, Richard Hipp wrote:
On 7/10/17, Jean-Marie CUAZ <jm.c...@orens.fr> wrote:
Hello,
Below is a recipe on a "best effort" basis, to truncate fp numbers on
the right side of the decimal separator with SQLite.
I don't understand how this is different from "round(N,3)"?
What are you trying to do to the fp number N that "round(N,3)" does not do?
What am I missing?
Well, Truncation is different from Rounding. Floor(N,3) would probably
be a closer match if that existed.
To demonstrate the difference in output, and also compare all the
methods offered, including one of mine, see the next results.
Simon's string method works well, but retains trailing zeroes, not sure
if this is acceptable to the OP, but I included a simple cast version to
fix that.
I believe Keith's and my methods will win (by a very small margin) on
speed tests, but they are certainly less complex.
I included two tests with both 3rd and 6th decimal truncation for all
methods using source values designed to be tricky:
(I hope the formatting holds)
-- SQLite version 3.17.0 [ Release: 2017-02-13 ] on SQLitespeed
version 2.0.2.4.
--
================================================================================================
WITH SRC(Val) AS (
VALUES
(0),(1.0000001),(1.12345678),(1.99999999),(1.888),(9.87654321),(1.555555555),(1.4999999),(1.49494999)
)
SELECT Val,
round(Val,3) AS Rounded,
printf('%0.3f', Val) AS PrntF,
round(CAST(Val AS INTEGER)+ (((Val * 1000) % 1000)/1000),3) AS
Tr_JeanM,
substr(Val||'0000',1,length(printf('%0.3f',Val))) AS Tr_Simon,
CAST(substr(Val||'0000',1,length(printf('%0.3f',Val))) AS REAL) AS
Tr_SimonFix,
CAST(Val*1000 AS INT) / 1000.0 AS Tr_Keith,
round(Val-0.000499999,3) AS Tr_Ryan
FROM SRC
;
-- | | | | | Tr_Simon-
| |
-- Val | Rounded | PrntF | Tr_JeanM | Tr_Simon
| Fix | Tr_Keith | Tr_Ryan
-- --------------- | --------- | --------- | --------- | --------- |
--------- | --------- | ---------
-- 0 | 0.0 | 0.000 | 0.0 | 00000
| 0.0 | 0.0 | 0.0
-- 1.0000001 | 1.0 | 1.000 | 1.0 | 1.000
| 1.0 | 1.0 | 1.0
-- 1.12345678 | 1.123 | 1.123 | 1.123 | 1.123
| 1.123 | 1.123 | 1.123
-- 1.99999999 | 2.0 | 2.000 | 1.999 | 1.999
| 1.999 | 1.999 | 1.999
-- 1.888 | 1.888 | 1.888 | 1.888 | 1.888
| 1.888 | 1.888 | 1.888
-- 9.87654321 | 9.877 | 9.877 | 9.876 | 9.876
| 9.876 | 9.876 | 9.876
-- 1.555555555 | 1.556 | 1.556 | 1.555 | 1.555
| 1.555 | 1.555 | 1.555
-- 1.4999999 | 1.5 | 1.500 | 1.499 | 1.499
| 1.499 | 1.499 | 1.499
-- 1.49494999 | 1.495 | 1.495 | 1.494 | 1.494
| 1.494 | 1.494 | 1.494
WITH SRC(Val) AS (
VALUES
(0),(1.0000001),(1.12345678),(1.99999999),(1.888),(9.87654321),(1.555555555),(1.4999999),(1.49494999)
)
SELECT Val,
round(Val,6) AS Rounded,
printf('%0.6f', Val) AS PrntF,
round(CAST(Val AS INTEGER)+ (((Val * 1000000) %
1000000)/1000000),6) AS Tr_JeanM,
substr(Val||'0000000',1,length(printf('%0.6f',Val))) AS Tr_Simon,
CAST(substr(Val||'0000000',1,length(printf('%0.6f',Val))) AS REAL) AS
Tr_SimonFix,
CAST(Val*1000000 AS INT) / 1000000.0 AS Tr_Keith,
round(Val-0.000000499999,6) AS Tr_Ryan
FROM SRC
;
-- Val | Rounded | PrntF | Tr_JeanM |
Tr_Simon | Tr_SimonFix | Tr_Keith | Tr_Ryan
-- --------------- | ------------ | ------------ | ------------ |
------------ | ------------ | ------------ | ------------
-- 0 | 0.0 | 0.000000 | 0.0 |
00000000 | 0.0 | 0.0 | 0.0
-- 1.0000001 | 1.0 | 1.000000 | 1.0 |
1.000000 | 1.0 | 1.0 | 1.0
-- 1.12345678 | 1.123457 | 1.123457 | 1.123456 |
1.123456 | 1.123456 | 1.123456 | 1.123456
-- 1.99999999 | 2.0 | 2.000000 | 1.999999 |
1.999999 | 1.999999 | 1.999999 | 1.999999
-- 1.888 | 1.888 | 1.888000 | 1.888 |
1.888000 | 1.888 | 1.888 | 1.888
-- 9.87654321 | 9.876543 | 9.876543 | 9.876543 |
9.876543 | 9.876543 | 9.876543 | 9.876543
-- 1.555555555 | 1.555556 | 1.555556 | 1.555555 |
1.555555 | 1.555555 | 1.555555 | 1.555555
-- 1.4999999 | 1.5 | 1.500000 | 1.499999 |
1.499999 | 1.499999 | 1.499999 | 1.499999
-- 1.49494999 | 1.49495 | 1.494950 | 1.494949 |
1.494949 | 1.494949 | 1.494949 | 1.494949
_______________________________________________
sqlite-users mailing list
sqlite-users@mailinglists.sqlite.org
http://mailinglists.sqlite.org/cgi-bin/mailman/listinfo/sqlite-users