【问题标题】:Handling Floating numbers in Pro*C在 Pro*C 中处理浮点数
【发布时间】:2013-10-14 20:23:44
【问题描述】:

我有一个带有 NUMBER 类型列的 Oracle 表,其中包含一系列浮点数。使用 Pro*C 将其读入 C 变量的正确方法是什么 我尝试了以下方法:

EXEC SQL BEGIN DECLARE SECTION;
static  float   o_start_x;
EXEC SQL END DECLARE SECTION;

EXEC SQL SELECT start_x
FROM  my_table
INTO  :o_start_x;

通常这不是很好,但是一些浮点数,特别是那些真正接近 0 的数(例如 1.4E-43)会导致以下错误:

ORA-01426: numeric overflow;

是否有正确/安全的读取此类值的方法,或者让 oracle 足够安全地转换类型的方法,从而允许精度损失?

【问题讨论】:

    标签: c oracle oracle-pro-c


    【解决方案1】:

    float 允许有限的精度 - double 有更多,通常是 15 位。

    警告:例如,浮点数在处理金钱时会出现问题。示例:.10 不能在数据的 IEEE-754 浮点内部表示中精确表示。一种常见的解决方法是让 oracle 使用 BCD 算法,避免浮点问题,然后将最终结果读入双精度数。

    FLT_DIG
    This is the number of decimal digits of precision for the float data type. Technically, if p and b are the precision and base (respectively) for the representation, then the decimal precision q is the maximum number of decimal digits such that any floating point number with q base 10 digits can be rounded to a floating point number with p base b digits and back again, without change to the q decimal digits.
    

    FLT_DIG 通常是最小精度六位数,DBL_DIG: 15。

    只要您避免在 C 代码中进行大量数学计算和比较,除非您知道如何处理我提到的问题和其他问题,否则很容易获得最终结果。

    EXEC SQL BEGIN DECLARE SECTION;
    static  double   o_start_x;
    EXEC SQL END DECLARE SECTION;
    
    EXEC SQL SELECT start_x
    FROM  my_table
    INTO  :o_start_x;
    

    如果这个数字很大,您可能必须使用字符串。 NUMBER 的限制是 32 位精度,这超出了常见 C 数据类型的精度限制。 Pro*C 不支持 bignum 数据类型,AFAIK。

    【讨论】:

    • .10 可以用 IEEE-754 decimal32、decimal64 和 decimal128 精确表示。 .10 无法在 IEEE-754 binary16、binary32、binary64 和 binary128 中精确表示。二进制格式更常见。
    • 你是对的,decimalnnn 并不通常在硬件中实现。你能说出拥有它的商品硬件吗?我不能。大型机可以。见:stackoverflow.com/questions/1447215/…
    • 我的评论不是针对硬件——而只是针对 IEEE-754 和 0.1 的想法。有许多十进制库实现。 Google-ing decimal64 想出了其中的一些。由于 Oracle 系统可能需要快速的十进制实现(即硬件),因此您的断言在本文的范围内可能是正确的,一般认为不是。 “你能说出商品硬件的名字吗……”听起来是个不错的问题,因为你提供的 4 年前的参考资料可能会受益于 2013 年的信息。
    • IEEE-754 2008 我认为是参考。
    猜你喜欢
    • 2014-04-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-16
    • 1970-01-01
    • 2016-09-28
    • 2014-05-19
    • 2023-03-17
    相关资源
    最近更新 更多