Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c > #29185 > unrolled thread

sscanf question

Started by"Brian O'Brien" <bjobrien62@gmail.com>
First post2012-12-12 13:29 -0800
Last post2012-12-14 12:25 +0000
Articles 20 on this page of 33 — 13 participants

Back to article view | Back to comp.lang.c


Contents

  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 →


#29185 — sscanf question

From"Brian O'Brien" <bjobrien62@gmail.com>
Date2012-12-12 13:29 -0800
Subjectsscanf 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]


#29187

From"BartC" <bc@freeuk.com>
Date2012-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]


#29188

FromJames Kuyper <jameskuyper@verizon.net>
Date2012-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]


#29195

FromLes Cargill <lcargill99@comcast.com>
Date2012-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]


#29202

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2012-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]


#29203

Fromfalk@rahul.net (Edward A. Falk)
Date2012-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]


#29204

FromPrathamesh Kulkarni <bilbotheelffriend@gmail.com>
Date2012-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]


#29208

FromFred K <fred.l.kleinschmidt@gmail.com>
Date2012-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]


#29209

FromFred K <fred.l.kleinschmidt@gmail.com>
Date2012-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]


#29210

From"BartC" <bc@freeuk.com>
Date2012-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]


#29213

FromKeith Thompson <kst-u@mib.org>
Date2012-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]


#29215

Fromglen herrmannsfeldt <gah@ugcs.caltech.edu>
Date2012-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]


#29216

From"BartC" <bc@freeuk.com>
Date2012-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]


#29218

Fromglen herrmannsfeldt <gah@ugcs.caltech.edu>
Date2012-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]


#29227

From"BartC" <bc@freeuk.com>
Date2012-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]


#29229

Fromglen herrmannsfeldt <gah@ugcs.caltech.edu>
Date2012-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]


#29233

From"BartC" <bc@freeuk.com>
Date2012-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]


#29246

Fromglen herrmannsfeldt <gah@ugcs.caltech.edu>
Date2012-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]


#29323

FromNick Keighley <nick_keighley_nospam@hotmail.com>
Date2012-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]


#29260

Fromfalk@rahul.net (Edward A. Falk)
Date2012-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