在进度4GL中,是否有一种方法可以将字符串转换为小数而不损失精度?



假设我需要将字符变量"0.0000000001"化为小数。但是如果我写出下面的逻辑:

define variable tinyChar as character initial "0.0000000001" no-undo.
define variable tinyNum as decimal no-undo.
assign tinyNum = decimal(tinyChar).
display tinyNum.

生成如下结果:

0.00

所以这一定不是解决方案,截断也会删除我想保留的数据。有人知道如何保持小数的精度吗?它不必是这种疯狂的情况,直到100亿,但至少有7或8个数字的精度将有助于解决我的问题。

变量(DEFINE VARIABLE语句)默认为最大10位小数,因此您不需要实际声明精度。

你的问题实际上是DISPLAY格式与内部数据表示和精度解耦(对于许多其他字段和变量属性(如字符串宽度)也是如此)。

这是一个特性。但对于刚接触OpenEdge的人来说,这是一个经常被绊倒的地方。通常认为显示格式限制了字段或变量的存储。但事实并非如此。(对于任何使用SQL访问数据的人来说都是非常懊恼的。)

您可以通过更改DEFINE variable来更改变量的默认格式,或者您可以在任何单独的DISPLAY中覆盖该格式。

所以需要对代码进行的最小更改是:

define variable tinyChar as character initial "0.0000000001" no-undo.
define variable tinyNum as decimal no-undo.
assign tinyNum = decimal(tinyChar).
display tinyNum format "9.9999999999".

无论DISPLAY格式如何,您可能对变量进行的任何计算都将使用所有10位小数。

数据库模式中定义的十进制字段(与变量相反)默认为2位小数。您可以在创建它们时更改。

赋给十进制字段或变量的计算值将被舍入到定义的精度。

根据doc[1], DECIMAL类型最多存储10位小数。如果你有更多,我认为它截断值。

[1] https://docs.progress.com/bundle/openedge-abl-reference-122/page/DEFINE-VARIABLE-statement.html

在定义DECIMAL变量时尝试使用DECIMALS和FORMAT选项:

define variable tinyChar as character initial "0.0000000001" no-undo.
define variable tinyNum  as decimal                          no-undo
DECIMALS 10 FORMAT "9.9999999999".
assign tinyNum = decimal(tinyChar).
display tinyNum.

考虑用常数(1000000或类似的东西)进行转换。甚至把它变成整数?对于这样小的浮点数,进度不是最好的环境。如果依赖计算精度就会受到影响!