Pro*C Rounding Solution ***
Date: 6 Dec 1994 00:40:26 -0500
Message-ID: <3c0tga$cp1_at_newsbf01.news.aol.com>
:culberso_at_tybrin.com (Mike Culberson) writes
:I am working on a SUN 630MP with Oracle 7.1.4.1.0, Pro*C 2.0.4.0.0, and
:SunOS 4.1.3_U1. The problem I am having is when I fetch a NUMBER column
from
:a table the value referenced in the host variable is not the exact
:number value in table. I am working with an accounting system and numbers
:need to be exact. Example of code follows.
:oracle_table
:------------
:
:val NUMBER(11,2) with a value of 1.55
:
:code
:----
:
:#include <stdio.h>
:
:EXEC SQL BEGIN DECLARE SECTION;
: double value;
: char oracleid = '/';
:EXEC SQL END DECLARE SECTION;
:
:EXEC SQL INCLUDE sqlca;
:
:main ()
:{
: EXEC SQL CONNECT oracleid;
:
: EXEC SQL SELECT val
: INTO :value
: FROM oracle_table;
:
: printf ("value = %15.30g\n",value);
:}
:
:If val is 1.55 the value printed out would be
1.55000000000000004440892098501
:
:Since I am dealing with multipling rates and calculating totals this
causes
:my totals to be off. So far the only way to ensure correct calculations
are
:to make all numbers integer within the Pro*C program. Are there any math
:libraries out there that would solve the problem.
First you might try using ROUND(val,2) on the select. So you'd have:
EXEC SQL SELECT ROUND(val,2) INTO :value FROM oracle_table;
If that doesn't work, you'll need to round the double variable. Enclosed is a function that I wrote and use all the time, it uses some C functions that I believe are common to most compilers ( this is from a MSC Compiler).
#include <stdio.h>
#include <math.h>
double rnd_dble( double dd, int i )
{
double l;
double w, x, y, z;
/* Seperate integer and fractional part of double */ x = modf( dd, &y );
/* Multiply fractional part, making an integer */ x = x * pow(10.0,i);
/* Test for sign */
l = 1.0;
if ( x < 0.0 ) l = -1.0;
/* Find integer largest integer less than or equal to fractional part */
z = floor(x);
w = x - z;
/* Check difference, so that we can round up or down */ if ( w > 0.49 ) z = z + 1.0;
/* Shift fractional part and add to original integer for rounded value
*/
y = y + ( z / pow(10.0,i) );
/* Set sign */
y = y * l;
return( y );
}
Hope this helps...
Lee Received on Tue Dec 06 1994 - 06:40:26 CET