Firebird在除法而不是舍入时会截断小数位。此外,它以分子和分母的小数位数为基础,将返回值的小数点位数作为基础。
为什么Firebird会被截断而不是四舍五入?为何将返回值基于查询中的小数位数?
Firebird2.5:
select 187/60.00 from rdb$database; --result: 3.11
select 187.000/60 from rdb$database; --result: 3.116
select 187.000/60.00 from rdb$database --result: 3.11666
SQL Server 2012:
select 187/60.00; --result: 3.116666
Oracle 11gR2:
select 187/60.00 from dual; --result: 3.116666666667
MySQL 5.5.32:
select 187/60.00 from dual; --result: 3.1167
PostgreSQL 9.3.1:
select 187/60.00; --result: 3.116666666667
SQLite:
select 187/60.00; --result: 3.1166666666666667
在Firebird中,带小数点的文字类型NUMERIC
不是DOUBLE PRECISION
(或其他浮点类型)。这意味着它将应用其确切的数值计算规则。
因此,select 187/60.00 from rdb$database
这意味着187是an,INTEGER
而60.00是a
NUMERIC(18,2)
。
精确数字计算的规则可以在“精确数字-功能说明”中找到:
如果两个操作数OP1和OP2分别是标度为S1和S2的精确数值,则OP1 +
OP2和OP1-OP2是精确度为18的精确数值,并标定S1和S2中的较大者,而OP1 * OP2和OP1 / OP2是精确数值精度为18,比例尺为S1
+
S2。(除除法运算外,这些操作的标度由SQL标准指定。该标准确定了所有这些运算的精度,除法的标度由实现定义:我们将精度定义为18,除法的标度定义为S1
+ S2,与乘法时标准所要求的相同。)
当操作数之一是整数类型时,它将被视为小数位数为0的数字。因此,在这种情况下,您具有,NUMERIC(18,0)/NUMERIC(18,2)
并根据上述规则,结果为NUMERIC(18, 0+2) = NUMERIC(18,2)
。
该数字似乎被截断的事实是应用精确数字计算的结果:一旦计算出最后一位数字,计算就会停止。存在余数的事实与计算结果无关:
60.00 / 187 \ 3.11
180
---
70
60
--
100
60
-- (stop)
40
看一下SQL:2011 Foundation规范,Firebird认为60.00
它是一个确切的数字是正确的,因为它在5.3
<literal> ::=
<signed numeric literal>
| <general literal>
<unsigned literal> ::=
<unsigned numeric literal>
| <general literal>
<signed numeric literal> ::=
[ <sign> ] <unsigned numeric literal>
<unsigned numeric literal> ::=
<exact numeric literal>
| <approximate numeric literal>
<exact numeric literal> ::=
<unsigned integer> [ <period> [ <unsigned integer> ] ]
| <period> <unsigned integer>
<sign> ::=
<plus sign>
| <minus sign>
<approximate numeric literal> ::=
<mantissa> E <exponent>
<mantissa> ::=
<exact numeric literal>
<exponent> ::=
<signed integer>
<signed integer> ::=
[ <sign> ] <unsigned integer>
<unsigned integer> ::=
<digit>...
和语法规则:
21)
<exact numeric literal>
没有a的<period>
an表示<period>
在last之后<digit>
。
22)<exact numeric literal>
ENL的声明类型是实现定义的精确数字类型,其小数位数是<digit>
右边的s数<period>
。应该有一个能够精确表示ENL值的精确数字类型。
第6.27节<数值表达式>指定以下语法规则:
1)如果二进位算术运算符的两个操作数的声明类型均为精确数值,则结果的声明类型为实现定义的精确数值类型,其精度和小数位数确定如下:
a)令S1和S2为第一和第二操作数的小数位数。
b)加法和减法结果的精度是实现定义的,并且小数位数是S1和S2的最大值。
c)乘法结果的精度是实现定义的,小数位数是S1 + S2。
d) 除法结果的精度和小数位数由实现定义。
换句话说,Firebird的行为符合SQL标准。从外观上看,您尝试过的大多数其他数据库(SQL
Server可能例外)要么在执行除法时使用相对较大的比例值,要么似乎使用近似数值(也称为双精度)行为。
一种解决方法是使用近似数字文字。使用零或指数E0
将使数字成为双精度,而没有额外的10的幂。例如:
select 187E0/60.00 from rdb$database; -- result: 3.116666666666667
-- or
select 187/60.00E0 from rdb$database; -- result: 3.116666666666667
我尝试在Jasper报告中格式化日期,它适用于Windows但不适用于Linux。对于Linux,结果文本被截断。 JRXML: Maven依赖关系: 我读到: 用jasperreport生成的PDF在Linux上显示不佳,但在Mac上显示良好,可能与os有关吗? http://community.jaspersoft.com/questions/527138/pdf-text-truncated
问题内容: 我如何获得1324343032.324? 如您在下面看到的,以下内容不起作用: 问题答案: 如果要将其保存为,可以在其周围使用其他内容。
问题内容: 我有一个长度为10 的类型的列: 在此列中,我插入了一个太长的数字: 当我查看表格中的内容时,数字现在是: 2147483647 变成了为什么,为什么? 为什么没有被截断? 这种转换背后的机制是什么,可以使用某些公式来计算结果数吗? 我不是在寻找解决方案。我只想了解具体数字。 问题答案: http://dev.mysql.com/doc/refman/5.0/en/integer- t
问题内容: 我有一个包含4列的表格:ID,类型,所有者,描述。ID是AUTO_INCREMENT PRIMARY KEY,现在我要: 当然,我很少有类型=’Apple’和owner =’Apple CO’的记录。因此,我的问题是,哪条记录将是保留在该ALTER TABLE之后的特殊记录,ID最小的记录或最新插入的最大记录? 问题答案: 第一条记录将保留,其余的将被删除§§: 是标准SQL的MySQ
我一直在监控我的应用程序错误,我看到下面的错误太多次了 错误:14077410:SSL例程:SSL23\u GET\u SERVER\u HELLO:sslv3警报握手失败(外部/openssl/SSL/s23\u clnt.c:741 0xaa48cd5c:0x00000000)-javax。网ssl。SSLHandshakeException:javax。网ssl。SSLProtocolExc
大家好,我最近更新了我的库,升级了改版和OKHTTP。我正在使用的新版本包括以下导入/版本: 3)OkHttp日志记录-编译'com.squareup.okhttp3:logging-interceptor:3.4.1' 4)reverfit-编译“com.squareup.reverfit2:reverfit:2.1.0” 5)改造Gson转换器-编译'com.squareup.retrofit