ARM Technical Support Knowledge Articles | |

**Applies to:** General Topics

Information in this article applies to:

- C166 All Versions
- C251 All Versions
- Cx51 All Versions

I'm using the **pow** function in my program and I have serious
problems with it. For example, the following code generates incorrect
results:

unsigned long v; v = 40 * pow(10,1); // gives correct result: 400 v = 40 * pow(10,3); // wrong result: 39999 (expected: 40000) v = 40 * pow(10,5); // wrong result: 4000004 (expected: 40000000) v = 40 * pow(10,7); // wrong result: 399999872 (expected: 4000000000)

Is this a problem with my code or a problem with the **pow**
function?

There is no problem with the **pow** function.

The problem is that the **pow** function accepts and returns
floating-point numbers (which have a maximum precision of 7 decimal
digits). The **exp** and **log** functions are used by
**pow** for its calculations. Therefore, there is an additional
loss of precision which yields the results you get.

Another effect is that float to long conversions are rounded-down. This is an ANSI requirement.

If you use the C166 or C251 compiler you can solve this issue by using the double arithmetic library.

If you use the C51 compiler or do not wish to use the double-precision arithmetic, you may rewrite your code as shown below to add +0.5 before the long conversion. This will give the results you expect.

v = (40 * pow(10,1)) + 0.5; v = (40 * pow(10,3)) + 0.5; v = (40 * pow(10,5)) + 0.5; v = (40 * pow(10,7)) + 0.5;

If the arguments to the **pow** function are integers, you may
consider using a series of multiplications instead.

- GENERAL: PRECISION OF PRINTF %F FORMAT STRING
- C166: DOUBLE PRECISION FLOATS TRUNCATED TO SINGLE PRECISION

**Article last edited on:** 2004-04-21 20:13:22

**Did you find this article helpful?** Yes No

**How can we improve this article?**