By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
445,813 Members | 1,252 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 445,813 IT Pros & Developers. It's quick & easy.

C floating point

P: n/a
C supports single precision floating point and double precision
floating point but does it support fixed floating point? i've read
that fixed floating point is more accurate than single precision
floating point when dealing with dollars and cents.
Nov 14 '05 #1
Share this Question
Share on Google+
24 Replies


P: n/a
j0******@engineer.com (j0mbolar) wrote:
C supports single precision floating point and double precision
floating point but does it support fixed floating point?


No, but it's pretty easy to simulate using integers.

Richard
Nov 14 '05 #2

P: n/a
On 1 Mar 2004 06:46:51 -0800, j0******@engineer.com (j0mbolar) wrote:
C supports single precision floating point and double precision
floating point but does it support fixed floating point?
Unfortunately,
a) "fixed" floatingpoint is a contradiction in terms. I believe you mean
"fixed point" (as opposed to "floating point" or "integer")
b) No, Standard C does not support "fixed floating point" (sic) numbers, neither
at the language level nor at the library level.
i've read
that fixed floating point is more accurate than single precision
floating point when dealing with dollars and cents.


--
Lew Pitcher
IT Consultant, Enterprise Application Architecture,
Enterprise Technology Solutions, TD Bank Financial Group

(Opinions expressed are my own, not my employers')
Nov 14 '05 #3

P: n/a
j0******@engineer.com (j0mbolar) writes:
C supports single precision floating point and double precision
floating point but does it support fixed floating point?
How can the point be both fixed and floating? I'm guessing that you mean
fixed point fractional numbers, i.e. something like 123.45, where there
are always 2 decimal digits after the point.
i've read that fixed floating point is more accurate than single
precision floating point when dealing with dollars and cents.


Just represent everything as cents internally and convert it on input or
output, e.g.

int amount = 12345; /* $123.45 */
printf ("The amount is $%d.%02d\n", amount / 100, amount % 100);

(A program which uses the $ character is not strictly conforming. You
can almost certainly ignore this limitation, though.)

Martin
--
,--. Martin Dickopp, Dresden, Germany ,= ,-_-. =.
/ ,- ) http://www.zero-based.org/ ((_/)o o(\_))
\ `-' `-'(. .)`-'
`-. Debian, a variant of the GNU operating system. \_/
Nov 14 '05 #4

P: n/a
In article <cu*************@zero-based.org>,
Martin Dickopp <ex****************@zero-based.org> wrote:
Just represent everything as cents internally and convert it on input or
output, e.g.

int amount = 12345; /* $123.45 */
printf ("The amount is $%d.%02d\n", amount / 100, amount % 100);


This won't work portably for negative amounts, and can portably
represent amounts aonly to $327.67

Francois Grieu
Nov 14 '05 #5

P: n/a
j0mbolar writes:
C supports single precision floating point and double precision
floating point but does it support fixed floating point? i've read
that fixed floating point is more accurate than single precision
floating point when dealing with dollars and cents.


No the language doesn't. but some compilers have BCD (binary coded decimal)
as an extension. I suspect that is what you want.
Nov 14 '05 #6

P: n/a
Francois Grieu wrote:

In article <cu*************@zero-based.org>,
Martin Dickopp <ex****************@zero-based.org> wrote:
Just represent everything as cents internally and convert it on input or
output, e.g.

int amount = 12345; /* $123.45 */
printf ("The amount is $%d.%02d\n", amount / 100, amount % 100);


This won't work portably for negative amounts, and can portably
represent amounts aonly to $327.67

Francois Grieu


IIRC, int is a signed integer, typically 16 bits. If he uses long it will be 32
bits,
so he can get numbers up to +- 21 Megabucks. That's enough for most of us unless
we are working for a major corporation or a government agency ("A billion here,
a
billion there, pretty soon it starts to add up to REAL money." -- Everett
Dirkson)

He can check it with

#include <stdio.h>

int main( void )
{
printf("The number of bytes in an int is %d.\n",sizeof(int));
printf("The number of bytes in a long int is %d.\n",sizeof(long));
return 0;
}

If more significant fixed-point figures are needed, he would have to define
quad-length signed integers. Not that hard, there are libraries. Google.

--
Julian V. Noble
Professor Emeritus of Physics
jv*@lessspamformother.virginia.edu
^^^^^^^^^^^^^^^^^^
http://galileo.phys.virginia.edu/~jvn/

"God is not willing to do everything, and thereby take away our free wiil
and that share of glory that rightfully belongs to ourselves."
-- N. Machiavelli, "The Prince".
Nov 14 '05 #7

P: n/a
"j0mbolar" <j0******@engineer.com> wrote in message
news:2d**************************@posting.google.c om...
C supports single precision floating point and double precision
floating point but does it support fixed floating point? i've read
that fixed floating point is more accurate than single precision
floating point when dealing with dollars and cents.


Fixed-point arithmetic, with a fractional part, is not a part of
Standard C. However TR 18037 includes fixed-point arithmetic as
part of its support for Embedded C. We'll have an implementation
later this year. Don't expect it to be more accurate, in general,
than floating-point.

By "more accurate," you might mean "less surprising in its rounding
and truncation behavior." For that you need decimal arithmetic.
And the C committee has just begun work on a non-normative binding
to IEEE 754R which will include a funky kind of decimal arithmetic
that behaves a little like fixed point and a lot like floating point.
But that's years out.

Your best bet for now is to do arithmetic using integers to count
pennies.

P.J. Plauger
Dinkumware, Ltd.
http://www.dinkumware.com
Nov 14 '05 #8

P: n/a
"Julian V. Noble" wrote:

He can check it [the widths of integer types] with

#include <stdio.h>

int main( void )
{
printf("The number of bytes in an int is %d.\n",sizeof(int));
printf("The number of bytes in a long int is %d.\n",sizeof(long));
return 0;
}


I have used a machine on which the output would be

The number of bytes in an int is 0.
The number of bytes in a long int is 0.

Quiz question 1: The predicted output is nonsense, so
something is clearly wrong. Is the implementation buggy,
or is there an error in the code?

Quiz question 2: How should the code be changed, either
to work around the implementation bug or to correct its
own error?

Bonus question: Once the bug is worked around or cured,
what would the output be? (Admittedly, I have not provided
enough information to answer with certainty. Still, it's
possible to make some pretty shrewd guesses.)

--
Er*********@sun.com
Nov 14 '05 #9

P: n/a
On Mon, 01 Mar 2004 14:24:59 -0500, Eric Sosman <Er*********@sun.com> wrote:
"Julian V. Noble" wrote:

He can check it [the widths of integer types] with

#include <stdio.h>

int main( void )
{
printf("The number of bytes in an int is %d.\n",sizeof(int));
printf("The number of bytes in a long int is %d.\n",sizeof(long));
return 0;
}
I have used a machine on which the output would be

The number of bytes in an int is 0.
The number of bytes in a long int is 0.

Quiz question 1: The predicted output is nonsense, so
something is clearly wrong. Is the implementation buggy,
or is there an error in the code?


There is an error in the code.
Quiz question 2: How should the code be changed, either
to work around the implementation bug or to correct its
own error?
Try
printf("The number of bytes in an int is %u.\n",
(unsigned)sizeof(int));
printf("The number of bytes in a long int is %u.\n",
(unsigned)sizeof(long));
Bonus question: Once the bug is worked around or cured,
what would the output be? (Admittedly, I have not provided
enough information to answer with certainty. Still, it's
possible to make some pretty shrewd guesses.)


Hmmm. A tricky one.

My first thought is that sizeof() represents some other unsigned integral value
other than that which can be represented in an unsigned int. This means that
sizeof evaluates to either
a) an unsigned char,
b) an unsigned short,
c) an unsigned long, or
d) an unsigned long long

Since integral promotion is required in variadic functions, an unsigned char and
an unsigned short would result in the printf() function obtaining an unsigned
int, and thus would produce the proper results. Since the proper results were
not produced, this means that sizeof evaluates to either an unsigned long or an
unsigned long long. Not many platforms that I know of do this.

So, we have a platform that evaluates sizeof into a long or long long. Since
that's unusual, I'd have to say that the platform is unusual. The few unusual
conforming platforms discussed around here are mostly 'embedded' systems,
usually DSPs and the like. IIRC, the common value discussed here is 64bits for
DSP words (I know it can differ, this is what I recollect appearing /here/, in
comp.lang.c). These sorts of embedded systems seem to either use CHAR_BITS=8, or
CHAR_BITS = wordsize.

Assuming CHAR_BITS == 8, then the likely output would be
The number of bytes in an int is 8.
The number of bytes in a long int is 8.

Assuming CHAR_BITS == wordsize, then the likely output would be
The number of bytes in an int is 1.
The number of bytes in a long int is 1.
--
Lew Pitcher
IT Consultant, Enterprise Application Architecture,
Enterprise Technology Solutions, TD Bank Financial Group

(Opinions expressed are my own, not my employers')
Nov 14 '05 #10

P: n/a

"Eric Sosman" <Er*********@sun.com> wrote in message
int main( void )
{
printf("The number of bytes in an int is %d.\n",sizeof(int));
printf("The number of bytes in a long int is %d.\n",sizeof
(long));
return 0;
}
I have used a machine on which the output would be

The number of bytes in an int is 0.
The number of bytes in a long int is 0.

Quiz question 1: The predicted output is nonsense, so
something is clearly wrong. Is the implementation buggy,
or is there an error in the code?

I think that the wicked implementation doesn't return an integer from
sizeof(), but an unsigned long. When 0x 0000 0002 is put on the stack, the
first 16 bits are interpreted as integer 0.
Quiz question 2: How should the code be changed, either
to work around the implementation bug or to correct its
own error?
Casting the sizeof() to an int would work.
Bonus question: Once the bug is worked around or cured,
what would the output be? (Admittedly, I have not provided
enough information to answer with certainty. Still, it's
possible to make some pretty shrewd guesses.)

The number of bytes in an int is 2
The number of bytes in a long int is 4

This assumes a 4GB address space and 32 bit size_t.
Nov 14 '05 #11

P: n/a

"j0mbolar" <j0******@engineer.com> wrote in message
C supports single precision floating point and double precision
floating point but does it support fixed floating point?
No. One idea is to use C++ and write your own "monetary" class. If you are
really clever you can make it hyper-inflation proof (when Mr Bush's deficit
stops being funded by the Japanese you might find that prices in dollar
terms go up rather faster than expected).
Financial applications aren't usually very maths-intensive, so it probably
won't matter if the internals are rather slow.
i've read
that fixed floating point is more accurate than single precision
floating point when dealing with dollars and cents.

The problem you have is that a binary system cannot represent 1/10 or 1/100
with complete accuracy. Fixed point won't solve this problem, but using a
decimal system will.
Nov 14 '05 #12

P: n/a
Supplemental reply below...

On Mon, 01 Mar 2004 20:09:00 GMT, Le*********@td.com (Lew Pitcher) wrote:
On Mon, 01 Mar 2004 14:24:59 -0500, Eric Sosman <Er*********@sun.com> wrote:
"Julian V. Noble" wrote:

He can check it [the widths of integer types] with

#include <stdio.h>

int main( void )
{
printf("The number of bytes in an int is %d.\n",sizeof(int));
printf("The number of bytes in a long int is %d.\n",sizeof(long));
return 0;
}
[snip] Bonus question: Once the bug is worked around or cured,
what would the output be? (Admittedly, I have not provided
enough information to answer with certainty. Still, it's
possible to make some pretty shrewd guesses.)
Hmmm. A tricky one.

[snip]Assuming CHAR_BITS == wordsize, then the likely output would be
The number of bytes in an int is 1.
The number of bytes in a long int is 1.


OK, this isn't right either.

Assuming that CHAR_BITS == wordsize, then the original printf() statements
should have resulted in non-zero values. That is to say, if the assumption that
sizeof(char) == sizeof(int) == sizeof(long int) == sizeof(long long int)
is true, then the original statement would have resulted in a sizeof that could
be printed using a "%d" without casting. Thus, it /would/ have printed proper
results.

Since it didn't, it is unlikely that the wordsize is used for all integral
types, and the assumptions that the above answer depends on are unreliable.
--
Lew Pitcher
IT Consultant, Enterprise Application Architecture,
Enterprise Technology Solutions, TD Bank Financial Group

(Opinions expressed are my own, not my employers')
Nov 14 '05 #13

P: n/a
In article <40***************@news21.on.aibn.com>,
Lew Pitcher <Le*********@td.com> wrote:

SNIP...

Try
printf("The number of bytes in an int is %u.\n",
(unsigned)sizeof(int));
printf("The number of bytes in a long int is %u.\n",
(unsigned)sizeof(long));


Try instead.
printf("The number of bytes in an int is %lu.\n",
(unsigned long)sizeof(int));
printf("The number of bytes in a long int is %lu.\n",
(unsigned long)sizeof(long));

Nov 14 '05 #14

P: n/a
j0******@engineer.com (j0mbolar) wrote in message news:<2d**************************@posting.google. com>...
C supports single precision floating point and double precision
floating point but does it support fixed floating point? i've read
that fixed floating point is more accurate than single precision
floating point when dealing with dollars and cents.


C doesn't have a built-in fixed data type. What you can do is use an
integral type, scaled to the smallest unit. For example, the integer
12345 may represent $123.45 (counting in cents), or $12.345 (counting
in tenths of cents), or $1.2345 (counting in hundredths of cents).

As you can see, the more precise the unit, the smaller the range. An
unsigned 16-bit integer can count from 0 to 65,535; if you're counting
in hundredths of cents, that gives you a range of $0 to $6.5535.

Alternately, you can use a struct with two members, one to keep track
of whole dollar amounts, the other to keep track of fractional
amounts:

struct val {
int dollar;
int fract;
};

so that the value $12.3456 is stored as {12, 3456}. This way you can
represent a larger range of dollars, yet still keep the precision you
want; unfortunately, the arithmetic gets a little hairier. Think
about adding the values $12.3456 and $45.82; you'll have to perform
some kind of addition on the struct values {12, 3456} and {45, 8200}.

You could also represent values as arrays of int, where each array
element corresponds to a digit (i.e., the value 123456789 is
represented as int val[]={1,2,3,4,5,6,7,8,9};); this way you can
represent values with tens or hundreds of significant digits. Again,
the math operations aren't as straightforward as for built-in types.
Nov 14 '05 #15

P: n/a
Malcolm wrote:

"Eric Sosman" <Er*********@sun.com> wrote in message
int main( void )
{
printf("The number of bytes in an int is %d.\n",sizeof(int));
printf("The number of bytes in a long int is %d.\n",sizeof
(long));
return 0;
}


I have used a machine on which the output would be

The number of bytes in an int is 0.
The number of bytes in a long int is 0.

Quiz question 1: The predicted output is nonsense, so
something is clearly wrong. Is the implementation buggy,
or is there an error in the code?

I think that the wicked implementation doesn't return an integer from
sizeof(), but an unsigned long. When 0x 0000 0002 is put on the stack, the
first 16 bits are interpreted as integer 0.

Quiz question 2: How should the code be changed, either
to work around the implementation bug or to correct its
own error?

Casting the sizeof() to an int would work.

Bonus question: Once the bug is worked around or cured,
what would the output be? (Admittedly, I have not provided
enough information to answer with certainty. Still, it's
possible to make some pretty shrewd guesses.)

The number of bytes in an int is 2
The number of bytes in a long int is 4

This assumes a 4GB address space and 32 bit size_t.


... and the Oscar goes to Malcolm!

Actually, the two sizes were 4 and 8, respectively, rather
than 2 and 4, but that's what my parenthetical remark was about.
The important thing is that `size_t' was wider than `int', and
that the "%d" conversion picked up the wrong part of the value.

--
Er*********@sun.com
Nov 14 '05 #16

P: n/a
Eric Sosman wrote:
"Julian V. Noble" wrote:

He can check it [the widths of integer types] with

#include <stdio.h>

int main( void )
{
printf("The number of bytes in an int is %d.\n",sizeof(int));
printf("The number of bytes in a long int is %d.\n",sizeof(long));
return 0;
}
I have used a machine on which the output would be

The number of bytes in an int is 0.
The number of bytes in a long int is 0.

Quiz question 1: The predicted output is nonsense, so
something is clearly wrong. Is the implementation buggy,
or is there an error in the code?


Error. Use "...%lu.\n", (unsigned long)sizeof(whatever));

Quiz question 2: How should the code be changed, either
to work around the implementation bug or to correct its
own error?

Bonus question: Once the bug is worked around or cured,
what would the output be? (Admittedly, I have not provided
enough information to answer with certainty. Still, it's
possible to make some pretty shrewd guesses.)


4 and 8. 2 and 4 is another possibility. The point is that size_t
must be bigger than an int.

For C99 the answers are different.

--
Chuck F (cb********@yahoo.com) (cb********@worldnet.att.net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net> USE worldnet address!
Nov 14 '05 #17

P: n/a
jd*@smof.fiawol.org (John Cochran) wrote:
In article <40***************@news21.on.aibn.com>,
Lew Pitcher <Le*********@td.com> wrote:
Try
printf("The number of bytes in an int is %u.\n",
(unsigned)sizeof(int));
printf("The number of bytes in a long int is %u.\n",
(unsigned)sizeof(long));


Try instead.
printf("The number of bytes in an int is %lu.\n",
(unsigned long)sizeof(int));
printf("The number of bytes in a long int is %lu.\n",
(unsigned long)sizeof(long));


Not likely to be necessary; I've never seen a system with larger than
8-byte ints, let alone larger than 32767-byte ints!

Richard
Nov 14 '05 #18

P: n/a
Richard Bos wrote:
jd*@smof.fiawol.org (John Cochran) wrote:
Lew Pitcher <Le*********@td.com> wrote:
Try
printf("The number of bytes in an int is %u.\n",
(unsigned)sizeof(int));
printf("The number of bytes in a long int is %u.\n",
(unsigned)sizeof(long));


Try instead.
printf("The number of bytes in an int is %lu.\n",
(unsigned long)sizeof(int));
printf("The number of bytes in a long int is %lu.\n",
(unsigned long)sizeof(long));


Not likely to be necessary; I've never seen a system with larger
than 8-byte ints, let alone larger than 32767-byte ints!


You miss the point. sizeof creates something of type size_t.
This may be significantly larger than an int, so lying to the
compiler about the parameter supplied to a variadic function
results in UB.

--
Chuck F (cb********@yahoo.com) (cb********@worldnet.att.net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net> USE worldnet address!
Nov 14 '05 #19

P: n/a
CBFalconer <cb********@yahoo.com> writes:
Richard Bos wrote:
jd*@smof.fiawol.org (John Cochran) wrote:
> Lew Pitcher <Le*********@td.com> wrote:
>
> >Try
> > printf("The number of bytes in an int is %u.\n",
> > (unsigned)sizeof(int));
> > printf("The number of bytes in a long int is %u.\n",
> > (unsigned)sizeof(long));
>
> Try instead.
> printf("The number of bytes in an int is %lu.\n",
> (unsigned long)sizeof(int));
> printf("The number of bytes in a long int is %lu.\n",
> (unsigned long)sizeof(long));
Not likely to be necessary; I've never seen a system with larger
than 8-byte ints, let alone larger than 32767-byte ints!


You miss the point. sizeof creates something of type size_t.
This may be significantly larger than an int,


The range of `size_t' may be significantly larger than the range of
`int', but that doesn't matter. As long as the /value/ returned by
`sizeof (int)' or `sizeof (long)' is guaranteed to fit in an `unsigned
int' (i.e. it is less than 32768), the cast to `unsigned int' is safe.
so lying to the compiler about the parameter supplied to a variadic
function results in UB.


Unless I'm missing something, this is not an issue here. Both variants
use %-specifications which match the argument.

Martin
--
,--. Martin Dickopp, Dresden, Germany ,= ,-_-. =.
/ ,- ) http://www.zero-based.org/ ((_/)o o(\_))
\ `-' `-'(. .)`-'
`-. Debian, a variant of the GNU operating system. \_/
Nov 14 '05 #20

P: n/a
In article <40***************@yahoo.com> cb********@worldnet.att.net writes:
Richard Bos wrote:
jd*@smof.fiawol.org (John Cochran) wrote: ....
> printf("The number of bytes in an int is %u.\n",
> (unsigned)sizeof(int)); .... printf("The number of bytes in an int is %lu.\n",
(unsigned long)sizeof(int));
.... You miss the point. sizeof creates something of type size_t.
This may be significantly larger than an int, so lying to the
compiler about the parameter supplied to a variadic function
results in UB.


You are missing the cast.
--
dik t. winter, cwi, kruislaan 413, 1098 sj amsterdam, nederland, +31205924131
home: bovenover 215, 1025 jn amsterdam, nederland; http://www.cwi.nl/~dik/
Nov 14 '05 #21

P: n/a
"Dik T. Winter" wrote:
cb********@worldnet.att.net writes:
> Richard Bos wrote:
> > jd*@smof.fiawol.org (John Cochran) wrote: ... > > > > printf("The number of bytes in an int is %u.\n",
> > > > (unsigned)sizeof(int)); ... > > > printf("The number of bytes in an int is %lu.\n",
> > > (unsigned long)sizeof(int));

...
> You miss the point. sizeof creates something of type size_t.
> This may be significantly larger than an int, so lying to the
> compiler about the parameter supplied to a variadic function
> results in UB.


You are missing the cast.


You're right. I was thinking of the original, which had no cast.

--
Chuck F (cb********@yahoo.com) (cb********@worldnet.att.net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net> USE worldnet address!
Nov 14 '05 #22

P: n/a
In <Jw*****************@nwrddc01.gnilink.net> "P.J. Plauger" <pj*@dinkumware.com> writes:
Your best bet for now is to do arithmetic using integers to count
pennies.


Your best bet for now is to use a scaling factor (so that you deal with
integer values) and use long double's (in C89) or long long's (in C99) for
storing and manipulating these integer values.

Dan
--
Dan Pop
DESY Zeuthen, RZ group
Email: Da*****@ifh.de
Nov 14 '05 #23

P: n/a
P.J. Plauger wrote:
Fixed-point arithmetic, with a fractional part,
is not a part of Standard C. However, TR 18037
Can I get any documentation on this?
And, if so, where?
includes fixed-point arithmetic as part of its support for Embedded C.
We'll have an implementation later this year.
Don't expect it to be more accurate, in general, than floating-point.


Nov 14 '05 #24

P: n/a
"E. Robert Tisdale" <E.**************@jpl.nasa.gov> wrote in message
news:40************@jpl.nasa.gov...
P.J. Plauger wrote:
Fixed-point arithmetic, with a fractional part,
is not a part of Standard C. However, TR 18037


Can I get any documentation on this?
And, if so, where?


http://std.dkuug.dk/JTC1/SC22/WG14/www/docs/n1021.pdf

P.J. Plauger
Dinkumware, Ltd.
http://www.dinkumware.com
Nov 14 '05 #25

This discussion thread is closed

Replies have been disabled for this discussion.