I have a C program that is running into problems rounding a float. The calculation is as follows

//faceamt = 5000000 and rate = 205.07

premium = (faceamt / 1000) * rate;

Round2Decimals(&premium);

//*******************************

void Round2Decimals(float *fn)

//********************************

{

long lrd;

double dg;

dg = ceil (*fn * 100);

if (dg - (double) *fn * 100 >= 0.51)

dg -= 1.0;

lrd = (long) dg;

*fn = (float) lrd / 100;

}

In the debugger, premium is calculated as 1.02535+e6 which appears to be correct. This value is then passed to a function to round it to two decimals...

The problem is that dg ends up with 102535007 which is incorrect. Where did the last two digits (07) come from and how can I avoid this without having to declare all variables as Doubles .

Thanks.

Upon further investigation...

I think the problem is typecasting a float to a double.

Example

float fltnum;

double dblnum;

fltnum = 205.07

dblnum = (double)fltnum;

//dblnum is now 205.07000732422. This is what is causing the problems...

//faceamt = 5000000 and rate = 205.07

premium = (faceamt / 1000) * rate;

Round2Decimals(&premium);

//************************

void Round2Decimals(float *fn)

//************************

{

long lrd;

double dg;

dg = ceil (*fn * 100);

if (dg - (double) *fn * 100 >= 0.51)

dg -= 1.0;

lrd = (long) dg;

*fn = (float) lrd / 100;

}

In the debugger, premium is calculated as 1.02535+e6 which appears to be correct. This value is then passed to a function to round it to two decimals...

The problem is that dg ends up with 102535007 which is incorrect. Where did the last two digits (07) come from and how can I avoid this without having to declare all variables as Doubles .

Thanks.

Upon further investigation...

I think the problem is typecasting a float to a double.

Example

float fltnum;

double dblnum;

fltnum = 205.07

dblnum = (double)fltnum;

//dblnum is now 205.07000732422. This is what is causing the problems...

If it is a float, then the line

Round2Decimals(premium);

is incorrect. You would need

Round2Decimals(&premium);

If it is a pointer, the line

premium = (faceamt / 1000) * rate;

is incorrect. You would need

*premium = (faceamt / 1000) * rate;

Hope this helps

This program works

#include <stdio.h>

#include <math.h>

//************************

void Round2Decimals(float *fn)

//************************

{

long lrd;

double dg;

dg = ceil (*fn * 100);

if (dg - (double) *fn * 100 >= 0.51)

dg -= 1.0;

lrd = (long) dg;

*fn = (float) lrd / 100;

}

void main()

{

float faceamt;

float rate;

float premium;

faceamt = (float)5000000;

rate = (float)205.07;

premium = (faceamt / 1000) * rate;

Round2Decimals(&premium);

}

I think, Float is not reliable after 7 digits.

#include <stdio.h>

#include <math.h>

//************************

void Round2Decimals(double *fn)

//************************

{

long lrd;

double dg;

dg = ceil (*fn * 100);

if (dg - (double) *fn * 100 >= 0.51)

dg -= 1.0;

lrd = (long) dg;

*fn = (float) lrd / 100;

}

void main()

{

double faceamt;

double rate;

double premium;

faceamt = (double)5000000.00;

rate = (double)205.07;

premium = (faceamt / 1000) * rate;

Round2Decimals(&premium);

}

Have you checked that your debugger display the full result of your variable. It looks to me that it uses a exponential format and displays only 6 digits.

floating point arithmetic', by David Goldberg (March 1991 Computing Surveys).

It carefully explains (among other useful stuff) what's happening when rounding,

converting and chopping floating point mantissas (significands).

kind regards,

Jos aka jos@and.nl

See jos' comment.

Also keep in mind that casting depends on the compiler, includes and processor type.

BTW,

fltnum = 205.07;

dblnum = (double)fltnum;

check fltnum, and you will see that it is 205.07000732422 too.

If you want to know what really happens, you need to print the value bit by bit, not using

any libc routine which reads a bunch of bits/bytes.

Also make shure that the variables are set to zero before using.

Please provide your email to receive a free trial preview!

*This site is protected by reCAPTCHA and the Google Privacy Policy and Terms of Service apply.