Domanda

I have an Oracle table with a column of type NUMBER, that contains a range of floating point numbers. What is the correct way to read that into a C variable using Pro*C I have tried the following:

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;

more often that not this is fine, however some floating point numbers, particularly those really close to 0 (e.g. 1.4E-43) causes the following errors:

ORA-01426: numeric overflow;

Is there a correct/safe way of reading such a value, or a method of having oracle convert the type safely enough, allowing for the loss of precision?

È stato utile?

Soluzione

float allows limited precision - double has more, 15 digits usually.

A caveat: floating point has issues when working with money, for example. Example: .10 cannot be exactly represented in IEEE-754 floating point internal representation of the data. A common workaround is to let oracle use BCD arithmetic, which avoids floating point issues, then read the final result into a double.

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 is normally six digits of precision minimum, DBL_DIG: 15.

As long as you avoid doing lots of math and compares in C code, unless you know how to deal with the issues I mentioned and other issues, getting a final result for money is easy.

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;

If this number is gigantic, you may have to use a string. The limit for NUMBER is 32 digits of precision, which exceeds the limits for precision for common C datatypes. Pro*C does not support bignum datatypes, AFAIK.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top