Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.c > #29185 > unrolled thread
| Started by | "Brian O'Brien" <bjobrien62@gmail.com> |
|---|---|
| First post | 2012-12-12 13:29 -0800 |
| Last post | 2012-12-14 12:25 +0000 |
| Articles | 20 on this page of 33 — 13 participants |
Back to article view | Back to comp.lang.c
sscanf question "Brian O'Brien" <bjobrien62@gmail.com> - 2012-12-12 13:29 -0800
Re: sscanf question "BartC" <bc@freeuk.com> - 2012-12-12 21:43 +0000
Re: sscanf question James Kuyper <jameskuyper@verizon.net> - 2012-12-12 16:52 -0500
Re: sscanf question Les Cargill <lcargill99@comcast.com> - 2012-12-12 22:14 -0600
Re: sscanf question Ben Bacarisse <ben.usenet@bsb.me.uk> - 2012-12-13 14:03 +0000
Re: sscanf question falk@rahul.net (Edward A. Falk) - 2012-12-13 20:36 +0000
Re: sscanf question Prathamesh Kulkarni <bilbotheelffriend@gmail.com> - 2012-12-13 13:40 -0800
Re: sscanf question Fred K <fred.l.kleinschmidt@gmail.com> - 2012-12-13 14:31 -0800
Re: sscanf question Fred K <fred.l.kleinschmidt@gmail.com> - 2012-12-13 14:33 -0800
Re: sscanf question "BartC" <bc@freeuk.com> - 2012-12-13 22:51 +0000
Re: sscanf question Keith Thompson <kst-u@mib.org> - 2012-12-13 15:45 -0800
Re: sscanf question glen herrmannsfeldt <gah@ugcs.caltech.edu> - 2012-12-14 00:06 +0000
Re: sscanf question "BartC" <bc@freeuk.com> - 2012-12-14 02:33 +0000
Re: sscanf question glen herrmannsfeldt <gah@ugcs.caltech.edu> - 2012-12-14 03:25 +0000
Re: sscanf question "BartC" <bc@freeuk.com> - 2012-12-14 11:50 +0000
Re: sscanf question glen herrmannsfeldt <gah@ugcs.caltech.edu> - 2012-12-14 12:19 +0000
Re: sscanf question "BartC" <bc@freeuk.com> - 2012-12-14 13:38 +0000
Re: sscanf question glen herrmannsfeldt <gah@ugcs.caltech.edu> - 2012-12-14 20:40 +0000
Re: sscanf question Nick Keighley <nick_keighley_nospam@hotmail.com> - 2012-12-16 03:34 -0800
Re: sscanf question falk@rahul.net (Edward A. Falk) - 2012-12-15 03:28 +0000
Re: sscanf question Les Cargill <lcargill99@comcast.com> - 2012-12-14 22:41 -0600
Re: sscanf question Keith Thompson <kst-u@mib.org> - 2012-12-15 01:25 -0800
Re: sscanf question glen herrmannsfeldt <gah@ugcs.caltech.edu> - 2012-12-15 10:26 +0000
Re: sscanf question Les Cargill <lcargill99@comcast.com> - 2012-12-15 13:24 -0600
Re: sscanf question glen herrmannsfeldt <gah@ugcs.caltech.edu> - 2012-12-15 20:15 +0000
Re: sscanf question Les Cargill <lcargill99@comcast.com> - 2012-12-15 15:33 -0600
[OT] Re: sscanf question Eric Sosman <esosman@comcast-dot-net.invalid> - 2012-12-15 17:49 -0500
Re: [OT] Re: sscanf question glen herrmannsfeldt <gah@ugcs.caltech.edu> - 2012-12-16 00:16 +0000
Re: sscanf question Barry Schwarz <schwarzb@dqel.com> - 2012-12-14 21:28 -0800
Re: sscanf question glen herrmannsfeldt <gah@ugcs.caltech.edu> - 2012-12-15 08:17 +0000
Re: sscanf question Eric Sosman <esosman@comcast-dot-net.invalid> - 2012-12-13 18:22 -0500
Re: sscanf question "Brian O'Brien" <bjobrien62@gmail.com> - 2012-12-13 21:13 -0800
Re: sscanf question Ben Bacarisse <ben.usenet@bsb.me.uk> - 2012-12-14 12:25 +0000
Page 1 of 2 [1] 2 Next page →
| From | "Brian O'Brien" <bjobrien62@gmail.com> |
|---|---|
| Date | 2012-12-12 13:29 -0800 |
| Subject | sscanf question |
| Message-ID | <ad54f74d-a4fe-42eb-a8e3-32a0597bd226@googlegroups.com> |
I am trying to extract a item description and price from a line of text. A Cup of Coffee $1.23 n = sscanf(str, "%s%*[\t $]%f", item, &price); But how can I make "A Cup of Coffee" as a single string? How does sscanf know that I don't want just the "A" of the sentence?
[toc] | [next] | [standalone]
| From | "BartC" <bc@freeuk.com> |
|---|---|
| Date | 2012-12-12 21:43 +0000 |
| Message-ID | <KU6ys.794258$Bz2.386305@fx11.am4> |
| In reply to | #29185 |
"Brian O'Brien" <bjobrien62@gmail.com> wrote in message news:ad54f74d-a4fe-42eb-a8e3-32a0597bd226@googlegroups.com... > I am trying to extract a item description and price from a line of text. > > A Cup of Coffee $1.23 > > n = sscanf(str, "%s%*[\t $]%f", item, &price); > > But how can I make "A Cup of Coffee" as a single string? How does sscanf > know that I don't want just the "A" of the sentence? First specify how you would know, anyway, where the description ends, and the price begins. If the description is in a fixed-width field, then you might not need sscanf at all. (And if variable width, I would probably use quotes around the description.) -- Bartc
[toc] | [prev] | [next] | [standalone]
| From | James Kuyper <jameskuyper@verizon.net> |
|---|---|
| Date | 2012-12-12 16:52 -0500 |
| Message-ID | <50C8FCB8.6030302@verizon.net> |
| In reply to | #29185 |
On 12/12/2012 04:29 PM, Brian O'Brien wrote: > I am trying to extract a item description and price from a line of text. > > A Cup of Coffee $1.23 > > n = sscanf(str, "%s%*[\t $]%f", item, &price); > > But how can I make "A Cup of Coffee" as a single string? How does sscanf know that I don't want just the "A" of the sentence? There's no easy way to make it accept the spaces within "A Cup of Coffee" without having it also accept the spaces between the second 'e' and the '$'. Would it be acceptable to include those spaces (and perhaps trim them off after they've been loaded into 'item'? Can you count on a '$' character always being present? If so, you could try the following: n = sscanf(str, "%[^$]$%f", item, &price); Bart's suggestion about using quotes to delimit the value of 'item' corresponds to the following: n = sscanf(str, "\"%[^\"]\"%*[\t $]%f", item, &price);
[toc] | [prev] | [next] | [standalone]
| From | Les Cargill <lcargill99@comcast.com> |
|---|---|
| Date | 2012-12-12 22:14 -0600 |
| Message-ID | <kabkld$qau$1@dont-email.me> |
| In reply to | #29185 |
Brian O'Brien wrote:
> I am trying to extract a item description and price from a line of text.
>
> A Cup of Coffee $1.23
>
> n = sscanf(str, "%s%*[\t $]%f", item, &price);
>
> But how can I make "A Cup of Coffee" as a single string? How does sscanf know that I don't want just the "A" of the sentence?
>
How reliable is the "$" token? strstr(s,"$") any help:
char s[] = "A Cup Of Coffee $1.23";
char *p = strstr(s,"$");
if (p!=NULL)
{
p++;
sscanf(...
}
--
Les Cargill
[toc] | [prev] | [next] | [standalone]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Date | 2012-12-13 14:03 +0000 |
| Message-ID | <0.5f3938f4e6ba633e3b5a.20121213140304GMT.87ip86jbhj.fsf@bsb.me.uk> |
| In reply to | #29195 |
Les Cargill <lcargill99@comcast.com> writes:
> Brian O'Brien wrote:
>> I am trying to extract a item description and price from a line of text.
>>
>> A Cup of Coffee $1.23
>>
>> n = sscanf(str, "%s%*[\t $]%f", item, &price);
>>
>> But how can I make "A Cup of Coffee" as a single string? How does sscanf know that I don't want just the "A" of the sentence?
>>
>
> How reliable is the "$" token? strstr(s,"$") any help:
>
> char s[] = "A Cup Of Coffee $1.23";
>
> char *p = strstr(s,"$");
> if (p!=NULL)
> {
> p++;
> sscanf(...
> }
I might not bother as one can test for the $ is the sscanf call by
explicitly matching it. I would, however, make a couple of other
refinements. First, I'd limit the length of string input to avoid
buffer overruns and, second, I'd add a couple of spaces into the format
to make it more flexible. Basically they mean that extra spaces alone
will never be the reason that the scan fails.
char b[10];
floar p;
if (sscanf(str, " %9[^$\t] $%f", b, &p) == 2) {
// good to go...
}
You still need to trim trailing spaces from b, but it's probably about
as close to what the OP wants as possible.
--
Ben.
[toc] | [prev] | [next] | [standalone]
| From | falk@rahul.net (Edward A. Falk) |
|---|---|
| Date | 2012-12-13 20:36 +0000 |
| Message-ID | <kade97$lta$2@blue-new.rahul.net> |
| In reply to | #29185 |
In article <ad54f74d-a4fe-42eb-a8e3-32a0597bd226@googlegroups.com>,
Brian O'Brien <bjobrien62@gmail.com> wrote:
>I am trying to extract a item description and price from a line of text.
>
>A Cup of Coffee $1.23
>
>n = sscanf(str, "%s%*[\t $]%f", item, &price);
>
>But how can I make "A Cup of Coffee" as a single string? How does sscanf know that I
>don't want just the "A" of the sentence?
You're dangerously close to needing to write your own parser or
using regexes, but I think this is do-able, as long as your
input format doesn't vary too much.
char item[80];
/* alphanum & blanks only */
n = sscanf(str, "%79[\t 0-9A-Za-z]$%f", item, &price);
OR
/* Anything but '$' */
n = sscanf(str, "%79[^$]$%f", item, &price);
You'll need to strip the trailing blanks from item. I don't think
there's a way to avoid that (unless you can guarantee that the separator
is a tab and there are no tabs in the item description).
Note the use of the field width. It's really not optional. This is a
security hole if you accept input from any untrusted source, and it's a
potential bug even if you do (someday, someone will edit that database
and not know about the length limitation.)
One final note: the use of float (or even double) to store monetary
amounts is looking for trouble. I speak from experience here.
--
-Ed Falk, falk@despams.r.us.com
http://thespamdiaries.blogspot.com/
[toc] | [prev] | [next] | [standalone]
| From | Prathamesh Kulkarni <bilbotheelffriend@gmail.com> |
|---|---|
| Date | 2012-12-13 13:40 -0800 |
| Message-ID | <65867183-4a71-4bdd-8e2d-7301aba0da00@googlegroups.com> |
| In reply to | #29203 |
On Thursday, 13 December 2012 15:36:55 UTC-5, Edward A. Falk wrote: > In article <ad54f74d-a4fe-42eb-a8e3-32a0597bd226@googlegroups.com>, > > Brian O'Brien <bjobrien62@gmail.com> wrote: > > >I am trying to extract a item description and price from a line of text. > > > > > >A Cup of Coffee $1.23 > > > > > >n = sscanf(str, "%s%*[\t $]%f", item, &price); > > > > > >But how can I make "A Cup of Coffee" as a single string? How does sscanf know that I > > >don't want just the "A" of the sentence? > > > > You're dangerously close to needing to write your own parser or > > using regexes, but I think this is do-able, as long as your > > input format doesn't vary too much. > > > > char item[80]; > > > > /* alphanum & blanks only */ > > n = sscanf(str, "%79[\t 0-9A-Za-z]$%f", item, &price); > > OR > > /* Anything but '$' */ > > n = sscanf(str, "%79[^$]$%f", item, &price); > > > > You'll need to strip the trailing blanks from item. I don't think > > there's a way to avoid that (unless you can guarantee that the separator > > is a tab and there are no tabs in the item description). > > > > Note the use of the field width. It's really not optional. This is a > > security hole if you accept input from any untrusted source, and it's a > > potential bug even if you do (someday, someone will edit that database > > and not know about the length limitation.) > > > > One final note: the use of float (or even double) to store monetary > > amounts is looking for trouble. I speak from experience here. > Please could you suggest some better ways than float/double to represent monetary amounts ? Thanks ;) > > > -- > > -Ed Falk, falk@despams.r.us.com > > http://thespamdiaries.blogspot.com/
[toc] | [prev] | [next] | [standalone]
| From | Fred K <fred.l.kleinschmidt@gmail.com> |
|---|---|
| Date | 2012-12-13 14:31 -0800 |
| Message-ID | <74e828e9-5f56-491d-b010-a5dd0cb4bd13@googlegroups.com> |
| In reply to | #29204 |
On Thursday, December 13, 2012 1:40:58 PM UTC-8, Prathamesh Kulkarni wrote: > On Thursday, 13 December 2012 15:36:55 UTC-5, Edward A. Falk wrote: > In article <ad54f74d-a4fe-42eb-a8e3-32a0597bd226@googlegroups.com>, > > Brian O'Brien <bjobrien62@gmail.com> wrote: > > >I am trying to extract a item description and price from a line of text. > > > > > >A Cup of Coffee $1.23 > > > > > >n = sscanf(str, "%s%*[\t $]%f", item, &price); > > > > > >But how can I make "A Cup of Coffee" as a single string? How does sscanf know that I > > >don't want just the "A" of the sentence? > > > > You're dangerously close to needing to write your own parser or > > using regexes, but I think this is do-able, as long as your > > input format doesn't vary too much. > > > > char item[80]; > > > > /* alphanum & blanks only */ > > n = sscanf(str, "%79[\t 0-9A-Za-z]$%f", item, &price); > > OR > > /* Anything but '$' */ > > n = sscanf(str, "%79[^$]$%f", item, &price); > > > > You'll need to strip the trailing blanks from item. I don't think > > there's a way to avoid that (unless you can guarantee that the separator > > is a tab and there are no tabs in the item description). > > > > Note the use of the field width. It's really not optional. This is a > > security hole if you accept input from any untrusted source, and it's a > > potential bug even if you do (someday, someone will edit that database > > and not know about the length limitation.) > > > > One final note: the use of float (or even double) to store monetary > > amounts is looking for trouble. I speak from experience here. > Please could you suggest some better ways than float/double to represent monetary amounts ? Thanks ;) > > > -- > > -Ed Falk, falk@despams.r.us.com > > http://thespamdiaries.blogspot.com/
[toc] | [prev] | [next] | [standalone]
| From | Fred K <fred.l.kleinschmidt@gmail.com> |
|---|---|
| Date | 2012-12-13 14:33 -0800 |
| Message-ID | <4be7ce8b-cc02-44e5-8824-246b832fd21f@googlegroups.com> |
| In reply to | #29208 |
On Thursday, December 13, 2012 2:31:41 PM UTC-8, Fred K wrote: > On Thursday, December 13, 2012 1:40:58 PM UTC-8, Prathamesh Kulkarni wrote: > On Thursday, 13 December 2012 15:36:55 UTC-5, Edward A. Falk wrote: > In article <ad54f74d-a4fe-42eb-a8e3-32a0597bd226@googlegroups.com>, > > Brian O'Brien <bjobrien62@gmail.com> wrote: > > >I am trying to extract a item description and price from a line of text. > > > > > >A Cup of Coffee $1.23 > > > > > >n = sscanf(str, "%s%*[\t $]%f", item, &price); > > > > > >But how can I make "A Cup of Coffee" as a single string? How does sscanf know that I > > >don't want just the "A" of the sentence? > > > > You're dangerously close to needing to write your own parser or > > using regexes, but I think this is do-able, as long as your > > input format doesn't vary too much. > > > > char item[80]; > > > > /* alphanum & blanks only */ > > n = sscanf(str, "%79[\t 0-9A-Za-z]$%f", item, &price); > > OR > > /* Anything but '$' */ > > n = sscanf(str, "%79[^$]$%f", item, &price); > > > > You'll need to strip the trailing blanks from item. I don't think > > there's a way to avoid that (unless you can guarantee that the separator > > is a tab and there are no tabs in the item description). > > > > Note the use of the field width. It's really not optional. This is a > > security hole if you accept input from any untrusted source, and it's a > > potential bug even if you do (someday, someone will edit that database > > and not know about the length limitation.) > > > > One final note: the use of float (or even double) to store monetary > > amounts is looking for trouble. I speak from experience here. > Please could you suggest some better ways than float/double to represent monetary amounts ? Thanks ;) > > > -- > > -Ed Falk, falk@despams.r.us.com > > http://thespamdiaries.blogspot.com/ Integer times 100 - i.e., in integer units of the smallest unit in the monetary system. So $1.23 is stored as 123 The reason is to avoid roundoff and truncation errors.
[toc] | [prev] | [next] | [standalone]
| From | "BartC" <bc@freeuk.com> |
|---|---|
| Date | 2012-12-13 22:51 +0000 |
| Message-ID | <p_sys.509618$Wc4.426891@fx10.am4> |
| In reply to | #29209 |
"Fred K" <fred.l.kleinschmidt@gmail.com> wrote in message news:4be7ce8b-cc02-44e5-8824-246b832fd21f@googlegroups.com... > On Thursday, December 13, 2012 2:31:41 PM UTC-8, Fred K wrote: >> On Thursday, December 13, 2012 1:40:58 PM UTC-8, Prathamesh Kulkarni >> wrote: > >> Please could you suggest some better ways than float/double to represent >> monetary amounts ? Thanks ;) > > > -- > > -Ed Falk, falk@despams.r.us.com >> > > http://thespamdiaries.blogspot.com/ > > Integer times 100 - i.e., in integer units of the smallest unit in the > monetary system. > > So $1.23 is stored as 123 > > The reason is to avoid roundoff and truncation errors. You still get problems when doing calculations (there are remainders to take care of). Floating point is workable if you know that an amount might be meant to represent a whole number of cents for example. Or you can use floating point to represent cents rather than dollars ... -- Bartc
[toc] | [prev] | [next] | [standalone]
| From | Keith Thompson <kst-u@mib.org> |
|---|---|
| Date | 2012-12-13 15:45 -0800 |
| Message-ID | <lnmwxhldo9.fsf@nuthaus.mib.org> |
| In reply to | #29210 |
"BartC" <bc@freeuk.com> writes:
> "Fred K" <fred.l.kleinschmidt@gmail.com> wrote in message
> news:4be7ce8b-cc02-44e5-8824-246b832fd21f@googlegroups.com...
>> On Thursday, December 13, 2012 2:31:41 PM UTC-8, Fred K wrote:
>>> On Thursday, December 13, 2012 1:40:58 PM UTC-8, Prathamesh Kulkarni
>>> wrote: >
>>> Please could you suggest some better ways than float/double to represent
>>> monetary amounts ? Thanks ;) > > > -- > > -Ed Falk, falk@despams.r.us.com
>>> > > http://thespamdiaries.blogspot.com/
>>
>> Integer times 100 - i.e., in integer units of the smallest unit in the
>> monetary system.
>>
>> So $1.23 is stored as 123
>>
>> The reason is to avoid roundoff and truncation errors.
>
> You still get problems when doing calculations (there are remainders to take
> care of).
>
> Floating point is workable if you know that an amount might be meant to
> represent a whole number of cents for example. Or you can use floating
> point to represent cents rather than dollars ...
Floating-point can't exactly represent all integer values within its
range -- and operations that yield inexact results generally don't give
any warning about a loss of precision. If you can guarantee that all
the numbers you'll be dealing with are within the contiguous range of
integers that can be represented exactly, then you'll probably be ok.
But then why use floating-point rather a large integer type in the first
place?
For *serious* financial calculations, there are typically standards that
specify exactly how those calculations are to be carried out. In such
contexts, you need to find those standards and follow them.
--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Will write code for food.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
[toc] | [prev] | [next] | [standalone]
| From | glen herrmannsfeldt <gah@ugcs.caltech.edu> |
|---|---|
| Date | 2012-12-14 00:06 +0000 |
| Message-ID | <kadqiq$rm5$1@speranza.aioe.org> |
| In reply to | #29213 |
Keith Thompson <kst-u@mib.org> wrote: (snip, someone wrote) >> Floating point is workable if you know that an amount might be meant to >> represent a whole number of cents for example. Or you can use floating >> point to represent cents rather than dollars ... > Floating-point can't exactly represent all integer values within its > range -- and operations that yield inexact results generally don't give > any warning about a loss of precision. If you can guarantee that all > the numbers you'll be dealing with are within the contiguous range of > integers that can be represented exactly, then you'll probably be ok. Also, as long as you don't do division. Well, it will work for a while, but can fail long before add, subtract, and multiply when the result is rounded differently than you expect. Now, with IEEE you know that the result is rounded. IBM S/360 (and HFP on newer processors) truncates the quotient (except on the 360/91 and related processors). The truncated quotient might be a better choice if you are using it for integer arithmetic. > But then why use floating-point rather a large integer type > in the first place? Yes, good question. In the days of 16 bit integers and 64 bit floating point, I know some used floating point for larger integer values, but now with 64 bit integers on most machines there isn't much of an excuse anymore. > For *serious* financial calculations, there are typically standards that > specify exactly how those calculations are to be carried out. In such > contexts, you need to find those standards and follow them. Yes. And also, as Knuth says, for typesetting. -- glen
[toc] | [prev] | [next] | [standalone]
| From | "BartC" <bc@freeuk.com> |
|---|---|
| Date | 2012-12-14 02:33 +0000 |
| Message-ID | <hfwys.1119952$Ol2.766606@fx25.am4> |
| In reply to | #29213 |
"Keith Thompson" <kst-u@mib.org> wrote in message news:lnmwxhldo9.fsf@nuthaus.mib.org... > "BartC" <bc@freeuk.com> writes: >> "Fred K" <fred.l.kleinschmidt@gmail.com> wrote in message >>> So $1.23 is stored as 123 >>> >>> The reason is to avoid roundoff and truncation errors. >> >> You still get problems when doing calculations (there are remainders to >> take >> care of). >> >> Floating point is workable if you know that an amount might be meant to >> represent a whole number of cents for example. Or you can use floating >> point to represent cents rather than dollars ... > Floating-point can't exactly represent all integer values within its > range 64-bit floats can still represent some $45 trillion dollars, even if you work in cents. Anything more than that, then perhaps you should make use of some 'serious' methods. But we're talking about the price of coffee. > -- and operations that yield inexact results generally don't give > any warning about a loss of precision. Integers aren't much better, when division is introduced. And division is necessary to do things like percentages. Unless the proposal is not only to use integers, but to use rationals so that you never get to do the division (but I'd be interested in how you'd print out the results!). > But then why use floating-point rather a large integer type in the first > place? Because integers don't do fractions very well. Not without using special methods, at which point it becomes easier to just use floating point. If you *know* that intermediate results need to be rounded to the nearest cent, for example, then you just round to the nearest cent (ie. to the nearest whole number). As far as add, subtract and multiply are concerned, calculating using floating point whole numbers is little different to using integers. But if you then have to calculate 15.9% tax on $53.49, it's a lot easier with floating point. (I've done this stuff where the total needed to be calculated in two separate currencies. The conversion rate between them was specified to four decimal places. Or you're buying by weight or length, and need to use either metric or Imperial measure. These things just aren't integer-friendly!) -- bartc
[toc] | [prev] | [next] | [standalone]
| From | glen herrmannsfeldt <gah@ugcs.caltech.edu> |
|---|---|
| Date | 2012-12-14 03:25 +0000 |
| Message-ID | <kae67t$isr$1@speranza.aioe.org> |
| In reply to | #29216 |
BartC <bc@freeuk.com> wrote: > "Keith Thompson" <kst-u@mib.org> wrote in message (snip) >> Floating-point can't exactly represent all integer values within its >> range > 64-bit floats can still represent some $45 trillion dollars, even if you > work in cents. Anything more than that, then perhaps you should make use of > some 'serious' methods. But we're talking about the price of coffee. >> -- and operations that yield inexact results generally don't give >> any warning about a loss of precision. > Integers aren't much better, when division is introduced. And division is > necessary to do things like percentages. Unless the proposal is not only to > use integers, but to use rationals so that you never get to do the division > (but I'd be interested in how you'd print out the results!). Integers are still a lot better. >> But then why use floating-point rather a large integer type in the first >> place? > Because integers don't do fractions very well. Not without using special > methods, at which point it becomes easier to just use floating point. > If you *know* that intermediate results need to be rounded to the nearest > cent, for example, then you just round to the nearest cent (ie. to the > nearest whole number). As far as add, subtract and multiply are concerned, > calculating using floating point whole numbers is little different to using > integers. But if you then have to calculate 15.9% tax on $53.49, it's a lot > easier with floating point. Take 5349 (cents) multiply by 159 and then divide by 1000 to get the truncated tax in cents. But with tax, you have to watch the rounding. If you want the rounded value, add 500 before dividing by 1000. Some years ago I lived in Maryland, where, as far as I could tell, the tax was rounded up. You can add from 0 to 999 before dividing depending on how you want it rounded. You do have to be sure that the intemediate doesn't overflow, but with 64 bit integers that shouldn't be hard. With floating point, the intermediate values might be rounded. You then have to be careful to avoid double rounding, which can give an unexpected wrong result. With integer division, you control the rounding. > (I've done this stuff where the total needed to be calculated in two > separate currencies. The conversion rate between them was specified to four > decimal places. Or you're buying by weight or length, and need to use either > metric or Imperial measure. These things just aren't integer-friendly!) Multiply be the value with four decimal places, after moving the decimal point to the right four places, then divide by 10000. Not hard at all. Again, add the appropriate amount before dividing to round as needed. -- glen
[toc] | [prev] | [next] | [standalone]
| From | "BartC" <bc@freeuk.com> |
|---|---|
| Date | 2012-12-14 11:50 +0000 |
| Message-ID | <IpEys.510821$Wc4.18818@fx10.am4> |
| In reply to | #29218 |
"glen herrmannsfeldt" <gah@ugcs.caltech.edu> wrote in message news:kae67t$isr$1@speranza.aioe.org... > BartC <bc@freeuk.com> wrote: >> Because integers don't do fractions very well. Not without using special >> methods, at which point it becomes easier to just use floating point. >> But if you then have to calculate 15.9% tax on $53.49, it's a lot >> easier with floating point. > > Take 5349 (cents) multiply by 159 and then divide by 1000 to get the > truncated tax in cents. But with tax, you have to watch the rounding. > If you want the rounded value, add 500 before dividing by 1000. OK, by using 'special methods' as I mentioned. You've now also introduced the arbitrary figures 10 (10*15.9), 500 and 1000, and presumably need to impose some arbitrary convention as to how percentage values are going to be represented in the program (I guess you can't just have 15.9 or 0.159). At this level of program, just using floating point is a lot easier! You just need to round to a cent at every stage, taking care when values are negative; one little function. > With floating point, the intermediate values might be rounded. Do you have a calculation where that rounding (which will be to the low-order bits of the representation) will actually give a different result to doing the whole thing with integers? (And with ordinary amounts that are likely to be encountered.) > Multiply be the value with four decimal places, after moving the decimal > point to the right four places, then divide by 10000. Not hard at all. No. Waste of time inventing floating point, really! -- Bartc
[toc] | [prev] | [next] | [standalone]
| From | glen herrmannsfeldt <gah@ugcs.caltech.edu> |
|---|---|
| Date | 2012-12-14 12:19 +0000 |
| Message-ID | <kaf5ge$ppe$1@speranza.aioe.org> |
| In reply to | #29227 |
BartC <bc@freeuk.com> wrote: (snip, someone wrote) >>> But if you then have to calculate 15.9% tax on $53.49, it's a lot >>> easier with floating point. (then I wrote) >> Take 5349 (cents) multiply by 159 and then divide by 1000 to get the >> truncated tax in cents. But with tax, you have to watch the rounding. >> If you want the rounded value, add 500 before dividing by 1000. > OK, by using 'special methods' as I mentioned. You've now also introduced > the arbitrary figures 10 (10*15.9), 500 and 1000, and presumably need to > impose some arbitrary convention as to how percentage values are going to be > represented in the program (I guess you can't just have 15.9 or 0.159). Well, you can do it in fixed point decimal just fine. If you write it in PL/I, instead of C, 15.9 is FIXED DECIMAL(3,1), that is, three digits with one after the decimal point. If you multiply, then the compiler knows what you mean and does it all for you, in fixed point. They added complex numbers to C, yet not many people use them. Maybe next we can have fixed decimal to make these calculations easier. > At this level of program, just using floating point is a lot easier! You > just need to round to a cent at every stage, taking care when values are > negative; one little function. >> With floating point, the intermediate values might be rounded. > Do you have a calculation where that rounding (which will be to the > low-order bits of the representation) will actually give a different result > to doing the whole thing with integers? (And with ordinary amounts that are > likely to be encountered.) With interest rates, it might be unusual, but, as previously mentioned, exchange rates often go to four decimal places. It won't take such big values to get rounding errors in that case. How long will it take you to show that they don't occur? You might look at: http://dl.acm.org/citation.cfm?id=221334 >> Multiply be the value with four decimal places, after moving the decimal >> point to the right four places, then divide by 10000. Not hard at all. > No. Waste of time inventing floating point, really! Floating point was invented for scientific problems that range over many orders of magnitude, and have inherent relative uncertainty. That is, the uncertainty scales with the value. In finance and typesetting, the uncertainty (cents or pixels) is fixed, independent of the size of the values. In the case of absolute uncertainty, fixed point arithmetic is a much better choice. Calculations in exadollars or femtodollars are pretty rare, but femtometers and exameters not so rare. (Nuclear physics and astrophysics, respectively.) It will take longer to prove that the rounding is right in floating point than to do it right in fixed point. -- glen
[toc] | [prev] | [next] | [standalone]
| From | "BartC" <bc@freeuk.com> |
|---|---|
| Date | 2012-12-14 13:38 +0000 |
| Message-ID | <Z_Fys.966881$Rc7.497512@fx04.am4> |
| In reply to | #29229 |
"glen herrmannsfeldt" <gah@ugcs.caltech.edu> wrote in message news:kaf5ge$ppe$1@speranza.aioe.org... > BartC <bc@freeuk.com> wrote: >>> With floating point, the intermediate values might be rounded. > >> Do you have a calculation where that rounding (which will be to the >> low-order bits of the representation) will actually give a different >> result >> to doing the whole thing with integers? (And with ordinary amounts that >> are >> likely to be encountered.) > With interest rates, it might be unusual, but, as previously mentioned, > exchange rates often go to four decimal places. It won't take such big > values to get rounding errors in that case. How long will it take you > to show that they don't occur? I'm asking you for *one* example where there might be a problem, but you're asking me to verify zillions of possible calculations? That's not fair! Actually I've now found my own examples where there might be differences. For example, 1% of $1234.50 (0.01*123450). Whenever a result has an odd 0.5 cents that needs to be rounded up or down (with different rounding methods, the problem just shifts elsewhere). Although neither integer nor floating point will give the 'right' answer, with integers it's possible to consistently round the same way. So you're right, although the intermediate rounding, while affecting which way it might go, has less to do with it than the errors in representing values such as 0.01. Of course you can just use whole number calculations as you suggested, but still using floating point; showing they are at least versatile! -- Bartc
[toc] | [prev] | [next] | [standalone]
| From | glen herrmannsfeldt <gah@ugcs.caltech.edu> |
|---|---|
| Date | 2012-12-14 20:40 +0000 |
| Message-ID | <kag2rl$90p$1@speranza.aioe.org> |
| In reply to | #29233 |
BartC <bc@freeuk.com> wrote: (snip, I wrote) >>>> With floating point, the intermediate values might be rounded. >>> Do you have a calculation where that rounding (which will be to the >>> low-order bits of the representation) will actually give a different >>> result >>> to doing the whole thing with integers? (And with ordinary amounts that >>> are >>> likely to be encountered.) >> With interest rates, it might be unusual, but, as previously mentioned, >> exchange rates often go to four decimal places. It won't take such big >> values to get rounding errors in that case. How long will it take you >> to show that they don't occur? > I'm asking you for *one* example where there might be a problem, > but you're asking me to verify zillions of possible calculations? > That's not fair! When you put your money in a bank, you want to know that they will do the interest computation right. You won't ask if they have an example where they did it wrong, but that they do it right under all conditions. Fortunately, you don't have to ask that because regulators will ask for you. -- glen
[toc] | [prev] | [next] | [standalone]
| From | Nick Keighley <nick_keighley_nospam@hotmail.com> |
|---|---|
| Date | 2012-12-16 03:34 -0800 |
| Message-ID | <d28e8b61-cfb5-4c01-94b4-ef57d5a67918@hf3g2000vbb.googlegroups.com> |
| In reply to | #29227 |
On Dec 14, 11:50 am, "BartC" <b...@freeuk.com> wrote: > "glen herrmannsfeldt" <g...@ugcs.caltech.edu> wrote in message > > news:kae67t$isr$1@speranza.aioe.org... > > > BartC <b...@freeuk.com> wrote: > >> Because integers don't do fractions very well. Not without using special > >> methods, at which point it becomes easier to just use floating point. > >> But if you then have to calculate 15.9% tax on $53.49, it's a lot > >> easier with floating point. > > > Take 5349 (cents) multiply by 159 and then divide by 1000 to get the > > truncated tax in cents. But with tax, you have to watch the rounding. > > If you want the rounded value, add 500 before dividing by 1000. > > OK, by using 'special methods' as I mentioned. You've now also introduced > the arbitrary figures 10 (10*15.9), 500 and 1000, and presumably need to > impose some arbitrary convention as to how percentage values are going to be > represented in the program (I guess you can't just have 15.9 or 0.159). > > At this level of program, just using floating point is a lot easier! You > just need to round to a cent at every stage, taking care when values are > negative; one little function. > > > With floating point, the intermediate values might be rounded. > > Do you have a calculation where that rounding (which will be to the > low-order bits of the representation) will actually give a different result > to doing the whole thing with integers? (And with ordinary amounts that are > likely to be encountered.) > > > Multiply be the value with four decimal places, after moving the decimal > > point to the right four places, then divide by 10000. Not hard at all. > > No. Waste of time inventing floating point, really! and rather horrid and easy to get wrong floating point! Fixed point is just nasty- leave it to the embedded programmers.
[toc] | [prev] | [next] | [standalone]
| From | falk@rahul.net (Edward A. Falk) |
|---|---|
| Date | 2012-12-15 03:28 +0000 |
| Message-ID | <kagqos$366$2@blue-new.rahul.net> |
| In reply to | #29209 |
In article <4be7ce8b-cc02-44e5-8824-246b832fd21f@googlegroups.com>, Fred K <fred.l.kleinschmidt@gmail.com> wrote: > >Integer times 100 - i.e., in integer units of the smallest unit in the monetary system. > >So $1.23 is stored as 123 > >The reason is to avoid roundoff and truncation errors. Well, when it comes time to compute the daily interest, there's really no way to avoid roundoff and truncation errors. We struggled with the problem for a month and never really solved it. Now I now know why people steal round-off error -- it really would have simplified things for us. But yes, at the very least don't use a format that has no representation for your unit of currency. There's no floating point representation of $.01. Even floating point would be acceptable as long as you multiplied by 100, e.g. 123.0 *is* an exact representation. -- -Ed Falk, falk@despams.r.us.com http://thespamdiaries.blogspot.com/
[toc] | [prev] | [next] | [standalone]
Page 1 of 2 [1] 2 Next page →
Back to top | Article view | comp.lang.c
csiph-web