perl中的指数值操作

时间:2017-05-03 16:44:46

标签: perl db2 exponential

我有一个select语句,它将容量作为指数值返回,例如

Capacity=5.4835615662E+003
Perl代码中的

我正在使用db2数据库,如果我在数据库中显式运行查询,则返回

5483.5615662

但是当我在条件中使用容量值时,我使用下一个选择查询

e.g。伪代码如下,

my $capacity = 'SELECT capacity FROM table';

# it returns $capacity = 5.4835615662E+003

my $result = "SELECT MEASUREMENT FROM TABLE WHERE CAPACITY = $capacity";

此处$capacity5.4835615662E+003,因此它与表格中的任何行都不匹配。它应该是5483.5615662

如何将指数值转换为float而不进行四舍五入?

2 个答案:

答案 0 :(得分:3)

您正在将$capacity的值插入到字符串中。相反,您应该使用placeholders,如下所示:

 my $sth = $dbh->prepare(q{SELECT MEASUREMENT FROM TABLE WHERE CAPACITY=?});
 $sth->execute($capacity);

很难说是否存在任何其他问题,因为您提供的代码段并没有真正做任何事情。

存储在数据库中的数字很可能不是5483.5615662,而只是查询时显示的字符串。

如果可能的话,我建议接受@Сухой27的建议并让数据库为你工作:

SELECT MEASUREMENT FROM TABLE
WHERE CAPACITY = (SELECT CAPACITY FROM TABLE where ..?)

或者,提前确定小数点后面的位数真正重要并使用ROUND或类似功能:

 my $sth = $dbh->prepare(q{
     SELECT MEASUREMENT FROM TABLE
     WHERE ROUND(CAPACITY, 6)=ROUND(?, 6)
 });
 $sth->execute($capacity);

答案 1 :(得分:1)

请查看Why doesn't this sql query return any results comparing floating point numbers?

我担心您在问题中显示的5.4835615662+003。这不是数字的有效表示,仅表示5.4835615662 + 3。在指数之前需要Ee来使用它,因为它是

comparing floating-point values也存在问题,其中两个基本相等的数字可能具有略微不同的二进制表示,因此不会相等。如果你的值已被转换为一个字符串(这似乎很有可能,因为Perl不会使用指数显示5483.5615662除非被告知这样做)并再次返回浮点数,那么它极不可能导致完全相同的值。你的比较总是失败

在Perl和大多数其他语言中,数值没有特定的格式。例如,如果我运行此

perl -E 'say 5.4835615662E+003'

我得到了输出

5483.5615662

显示两个字符串表示是等效的

有助于确切了解如何从数据库中获取$capacity的值,因为如果它是一个简单的数字,那么它就不会使用科学表示。你必须使用sprintf来获得你所展示的内容

SQL是相同的,只要它有效,就不关心数字的格式,所以如果你写了

SELECT measurement FROM table WHERE capacity = 5.4835615662E+003

然后您会得到capacity 完全 等于该值的结果。但由于它已被修剪为11位有效数字,因此您极不可能找到该值来自的记录,除非它包含5483.56156620000000000


更新

如果我跑

perl -MMath::Trig=pi -E 'for (0 .. 20) { $x = pi * 10**$_; say qq{$x}; }'

我得到了这个结果

3.14159265358979
31.4159265358979
314.159265358979
3141.59265358979
31415.9265358979
314159.265358979
3141592.65358979
31415926.5358979
314159265.358979
3141592653.58979
31415926535.8979
314159265358.979
3141592653589.79
31415926535897.9
314159265358979
3.14159265358979e+015
3.14159265358979e+016
3.14159265358979e+017
3.14159265358979e+018
3.14159265358979e+019
3.14159265358979e+020

因此,默认情况下,Perl 不会使用科学记数法,直到值达到10 15 。它显然不适用于5483.5615662。有些东西已经将问题中的浮点值强制转换为科学记数法中不那么精确的字符串。比较平等并没有成功的机会