473,463 Members | 1,380 Online
Bytes | Software Development & Data Engineering Community
Create Post

Home Posts Topics Members FAQ

Bug/Gross InEfficiency in HeathField's fgetline program

The function below is from Richard HeathField's fgetline program. For
some reason, it makes three passes through the string (a strlen(), a
strcpy() then another pass to change dots) when two would clearly be
sufficient. This could lead to unnecessarily bad performance on very
long strings. It is also written in a hard-to-read and clunky style.

char *dot_to_underscore(const char *s)
{
char *t = malloc(strlen(s) + 1);
if(t != NULL)
{
char *u;
strcpy(t, s);
u = t;
while(*u)
{
if(*u == '.')
{
*u = '_';
}
++u;
}
}
return
t;
}

Proposed solution:

char *dot_to_underscore(const char *s)
{
char *t, *u;
if(t=u=malloc(strlen(s)+1))
while(*u++=(*s=='.' ? s++, '_' : *s++));
return t;
}

Oct 7 '07
334 11248
"pete" <pf*****@mindspring.coma écrit dans le message de news:
47***********@mindspring.com...
Kelsey Bjarnason wrote:
>>
[snips]

On Tue, 23 Oct 2007 22:21:50 +0100, Malcolm McLean wrote:
>Surely size_t is tailormade for this purpose?
Yes. There are two main snags.
Firstly it is unsigned.

Which makes sense, given that it is intended to be used to hold sizes,
which can never be negative, and indexes which, likewise, can never be
negative.
Although array indicies are naturally positive,
intermediate calculations can produce negative values.

Damned rarely, IME.

I don't see what difference the negativity of
intermediate calculations makes anyway.

(0u - 10 + 15) is an expression of type unsigned,
with a value of 5u.
He was probably thinking of this kind of issue:

index_t find_last(const int *array, index_t len, int val) {
index_t i;
for (i = len - 1; i >= 0; i--) {
if (array[i] == val)
return i;
}
return -1;
}

If index_t is an unsigned type, the loop never ends and big fat undefined
behaviour strikes!
if index_t is signed (such as non-standard ssize_t) the code works just
fine.

--
Chqrlie.
Oct 26 '07 #201
Charlie Gordon wrote:
"pete" <pf*****@mindspring.coma écrit dans le message de news:
47***********@mindspring.com...
>Kelsey Bjarnason wrote:
>>>
[snips]

On Tue, 23 Oct 2007 22:21:50 +0100, Malcolm McLean wrote:

Surely size_t is tailormade for this purpose?

Yes. There are two main snags.

Firstly it is unsigned.

Which makes sense, given that it is intended to be used to hold
sizes, which can never be negative, and indexes which, likewise, can
never be negative.

Although array indicies are naturally positive,
intermediate calculations can produce negative values.

Damned rarely, IME.

I don't see what difference the negativity of
intermediate calculations makes anyway.

(0u - 10 + 15) is an expression of type unsigned,
with a value of 5u.

He was probably thinking of this kind of issue:

index_t find_last(const int *array, index_t len, int val) {
index_t i;
for (i = len - 1; i >= 0; i--) {
if (array[i] == val)
return i;
}
return -1;
}

If index_t is an unsigned type, the loop never ends and big fat
undefined behaviour strikes!
if index_t is signed (such as non-standard ssize_t) the code works
just fine.
If you're really enamoured of this form of loop control then long should
do, or if you need to address above 4Gb then long long.

Oct 26 '07 #202
"santosh" <sa*********@gmail.coma écrit dans le message de news:
ff**********@registered.motzarella.org...
Charlie Gordon wrote:
>"pete" <pf*****@mindspring.coma écrit dans le message de news:
47***********@mindspring.com...
>>Kelsey Bjarnason wrote:

[snips]

On Tue, 23 Oct 2007 22:21:50 +0100, Malcolm McLean wrote:

Surely size_t is tailormade for this purpose?

Yes. There are two main snags.

Firstly it is unsigned.

Which makes sense, given that it is intended to be used to hold
sizes, which can never be negative, and indexes which, likewise, can
never be negative.

Although array indicies are naturally positive,
intermediate calculations can produce negative values.

Damned rarely, IME.

I don't see what difference the negativity of
intermediate calculations makes anyway.

(0u - 10 + 15) is an expression of type unsigned,
with a value of 5u.

He was probably thinking of this kind of issue:

index_t find_last(const int *array, index_t len, int val) {
index_t i;
for (i = len - 1; i >= 0; i--) {
if (array[i] == val)
return i;
}
return -1;
}

If index_t is an unsigned type, the loop never ends and big fat
undefined behaviour strikes!
if index_t is signed (such as non-standard ssize_t) the code works
just fine.

If you're really enamoured of this form of loop control then long should
do, or if you need to address above 4Gb then long long.
I am not "enamoured" with this kind of loop, I was just giving an example of
problems that arise when using unsigned types because of the discontinuity
at zero.
I would probably use ssize_t and define it if not available on the target
architecture.
The loop should be written as follows:

index_t find_last(const int *array, index_t len, int val) {
index_t i;
for (i = len; i-- 0; ) {
if (array[i] == val)
return i;
}
return -1;
}

--
Chqrlie.
Oct 26 '07 #203
"Malcolm McLean" <re*******@btinternet.comwrites:
"pete" <pf*****@mindspring.comwrote in message
>>
I don't see what difference the negativity of
intermediate calculations makes anyway.

(0u - 10 + 15) is an expression of type unsigned,
with a value of 5u.
If only C guaranteed you an overflow error in such a situation.
<snip>

The list of things you like in C is looking smaller and smaller.
Also, the list of things you want all programs to pay the cost of is
getting longer. To paraphrase Oscar Wilde: "A language cynic knows
the cost of everything and the value of nothing". One of C's main
advantages is the fact that, by leaving so much unspecified, compilers
can generate efficient code on a wide range of hardware.

The cost is, of course, more care required when writing the code, but
other languages are usually available that have made a different
contract between programmer and hardware.

--
Ben.
Oct 26 '07 #204
Charlie Gordon wrote:
>
"santosh" <sa*********@gmail.coma écrit dans le message de news:
ff**********@registered.motzarella.org...
Charlie Gordon wrote:
"pete" <pf*****@mindspring.coma écrit dans le message de news:
47***********@mindspring.com...
Kelsey Bjarnason wrote:

[snips]

On Tue, 23 Oct 2007 22:21:50 +0100, Malcolm McLean wrote:

Surely size_t is tailormade for this purpose?

Yes. There are two main snags.

Firstly it is unsigned.

Which makes sense, given that it is intended to be used to hold
sizes, which can never be negative,
and indexes which, likewise, can never be negative.

Although array indicies are naturally positive,
intermediate calculations can produce negative values.

Damned rarely, IME.

I don't see what difference the negativity of
intermediate calculations makes anyway.

(0u - 10 + 15) is an expression of type unsigned,
with a value of 5u.

He was probably thinking of this kind of issue:

index_t find_last(const int *array, index_t len, int val) {
index_t i;
for (i = len - 1; i >= 0; i--) {
if (array[i] == val)
return i;
}
return -1;
}
The loop should be written as follows:

index_t find_last(const int *array, index_t len, int val) {
index_t i;
for (i = len; i-- 0; ) {
if (array[i] == val)
return i;
}
return -1;
}
Even Malcolm McLean, who doesn't like size_t,
knows how to use size_t *that* well.

http://groups.google.com/group/comp....fac381c99339e3

Malcolm McLean wrote:
"christian.bau" <christian....@cbau.wanadoo.co.uk>
wrote in message
news:11**********************@r29g2000hsg.googlegr oups.com...
for (i = strlen (s) - 1; i >= 0; --i) ...
Now write that with an unsigned type
without any convoluted code.
size_t i = strlen(s);
while(i--)
{
/* loop body */
}
But christian.bau's post was disturbing.

--
pete
Oct 26 '07 #205

"Ben Pfaff" <bl*@cs.stanford.eduwrote in message
"Malcolm McLean" <re*******@btinternet.comwrites:
>Secondly it is called size_t. If I was supreme ruler of the universe I
could force everyone to use it, but I'm not, and there's just no way
you are going to get consistent usage of a type called "size_t" for an
index variable.

What's wrong with the name size_t?
The underscore is unacceptable in something so fundamental.
The name looks like it ought to hold an amount of memory in bytes. In fact
that was the oriignal intention. But actually only a tiny minority of
size_ts are used for that. You need it every time you use an array whose
maximum dimension you cannot control, for both the count and the index.
Which in fact is almost every integer.

So Flash's cache usage objection to 64 bit int actually vanishes, unless we
are writing a mishmash of int and size_t indexed code which risks breaking
when the two sizes diverge. You cannot save on cache space by changing the
spelling of a type. What you can do is discourage good practise, and make it
harder to fit code together.

--
Free games and programming goodies.
http://www.personal.leeds.ac.uk/~bgy1mm

Oct 27 '07 #206
Malcolm McLean wrote:
>
"Ben Pfaff" <bl*@cs.stanford.eduwrote in message
>"Malcolm McLean" <re*******@btinternet.comwrites:
>>Secondly it is called size_t. If I was supreme ruler of the universe
I could force everyone to use it, but I'm not, and there's just no
way you are going to get consistent usage of a type called "size_t"
for an index variable.

What's wrong with the name size_t?
The underscore is unacceptable in something so fundamental.
That's just a style consideration.
The name looks like it ought to hold an amount of memory in bytes. In
fact that was the oriignal intention.
Yes.
But actually only a tiny minority of size_ts are used for that. You
need it every time you use an array whose maximum dimension you cannot
control, for both the count and the index.
IMHO, both uses are related. Since array indices are a subset of the
array's size, size_t is just as appropriate for both purposes.
Which in fact is almost every integer.
Maybe this is true in the sort of programming you do, but there are many
programs where integers are needed for arithmetic far more than
indexing.

<snip>

Oct 27 '07 #207
"santosh" <sa*********@gmail.comwrote in message
Malcolm McLean wrote:
>Which in fact is almost every integer.

Maybe this is true in the sort of programming you do, but there are many
programs where integers are needed for arithmetic far more than
indexing.
I'm pretty sure that's a perception rather than a reality. Let's say you are
storing a list of amounts of money as integers. You write a routine to take
the average. When asked "what does this routine do" you will answer "it adds
up an amount of money, divides by the count, and reports it."
Actually that's not what it does.

int average(int *money, size_t N)
{
size_t i;
int total = 0;

for(i=0;i<N;i++)
total += money[i];
return total/N;
}

Whilst there are two operations that operate on int (total =0, total +=),
there are four which operate on i, and one which operates on total and N.
Whether you count C instructions or machine operations, what the function is
mainly doing is calculating a list of indices.
However the programmer's perception will be that he is mainly working with
amounts of money, because that is what is important to his human-centric way
of looking at the routine.

--
Free games and programming goodies.
http://www.personal.leeds.ac.uk/~bgy1mm

Oct 27 '07 #208
"Malcolm McLean" <re*******@btinternet.comwrites:
"santosh" <sa*********@gmail.comwrote in message
>Malcolm McLean wrote:
>>Which in fact is almost every integer.

Maybe this is true in the sort of programming you do, but there are many
programs where integers are needed for arithmetic far more than
indexing.
I'm pretty sure that's a perception rather than a reality. Let's say
you are storing a list of amounts of money as integers. You write a
routine to take the average. When asked "what does this routine do"
you will answer "it adds up an amount of money, divides by the count,
and reports it."
Actually that's not what it does.

int average(int *money, size_t N)
{
size_t i;
int total = 0;

for(i=0;i<N;i++)
total += money[i];
return total/N;
}

Whilst there are two operations that operate on int (total =0, total
+=), there are four which operate on i, and one which operates on
No there are not. it depends what the compiler does. You could as easily
make it 1 one off for initilisation and one for the loop and check

int i=N;
while(i--)
total += money[i];
total and N. Whether you count C instructions or machine operations,
what the function is mainly doing is calculating a list of indices.
Its not mainly doing that at all. It is mainly accessing and adding up numbers.
However the programmer's perception will be that he is mainly working
with amounts of money, because that is what is important to his
human-centric way of looking at the routine.
You confuse me by trying to think too much into it.

This function adds a set integers together and then returns the average.

Oct 27 '07 #209
"Richard" <rg****@gmail.coma écrit dans le message de news:
56************@news.individual.net...
"Malcolm McLean" <re*******@btinternet.comwrites:
>"santosh" <sa*********@gmail.comwrote in message
>>Malcolm McLean wrote:

Which in fact is almost every integer.

Maybe this is true in the sort of programming you do, but there are many
programs where integers are needed for arithmetic far more than
indexing.
I'm pretty sure that's a perception rather than a reality. Let's say
you are storing a list of amounts of money as integers. You write a
routine to take the average. When asked "what does this routine do"
you will answer "it adds up an amount of money, divides by the count,
and reports it."
Actually that's not what it does.

int average(int *money, size_t N)
{
size_t i;
int total = 0;

for(i=0;i<N;i++)
total += money[i];
return total/N;
}

Whilst there are two operations that operate on int (total =0, total
+=), there are four which operate on i, and one which operates on

No there are not. it depends what the compiler does. You could as easily
make it 1 one off for initilisation and one for the loop and check

int i=N;
while(i--)
total += money[i];
>total and N. Whether you count C instructions or machine operations,
what the function is mainly doing is calculating a list of indices.

Its not mainly doing that at all. It is mainly accessing and adding up
numbers.
>However the programmer's perception will be that he is mainly working
with amounts of money, because that is what is important to his
human-centric way of looking at the routine.

You confuse me by trying to think too much into it.

This function adds a set integers together and then returns the average.
That's what it attempts to do, but the calculation is quite likely to cause
integer overflow if the array and/or values are large enough, causing
undefined behaviour. Otherwise, the result is the average of the values of
the array, rounded towards zero. If the size N passed is zero, undefined
behaviour is invoked.

--
Chqrlie.
Oct 27 '07 #210
"Charlie Gordon" <ne**@chqrlie.orgwrites:
"Richard" <rg****@gmail.coma écrit dans le message de news:
56************@news.individual.net...
>"Malcolm McLean" <re*******@btinternet.comwrites:
>>"santosh" <sa*********@gmail.comwrote in message
Malcolm McLean wrote:

Which in fact is almost every integer.

Maybe this is true in the sort of programming you do, but there are many
programs where integers are needed for arithmetic far more than
indexing.

I'm pretty sure that's a perception rather than a reality. Let's say
you are storing a list of amounts of money as integers. You write a
routine to take the average. When asked "what does this routine do"
you will answer "it adds up an amount of money, divides by the count,
and reports it."
Actually that's not what it does.

int average(int *money, size_t N)
{
size_t i;
int total = 0;

for(i=0;i<N;i++)
total += money[i];
return total/N;
}

Whilst there are two operations that operate on int (total =0, total
+=), there are four which operate on i, and one which operates on

No there are not. it depends what the compiler does. You could as easily
make it 1 one off for initilisation and one for the loop and check

int i=N;
while(i--)
total += money[i];
>>total and N. Whether you count C instructions or machine operations,
what the function is mainly doing is calculating a list of indices.

Its not mainly doing that at all. It is mainly accessing and adding up
numbers.
>>However the programmer's perception will be that he is mainly working
with amounts of money, because that is what is important to his
human-centric way of looking at the routine.

You confuse me by trying to think too much into it.

This function adds a set integers together and then returns the average.

That's what it attempts to do, but the calculation is quite likely to cause
integer overflow if the array and/or values are large enough, causing
Its not quite likely to do anything of the sort if it is operating in
the limits the designer set - otherwise we would use different types.
undefined behaviour. Otherwise, the result is the average of the values of
the array, rounded towards zero. If the size N passed is zero, undefined
behaviour is invoked.
I'm not sure I understand why you are writing this. This applies to any
and all code posted here and a code review isn't the issue here.

Anytime someone posts a line like

x+=y;

One could make this comment "that addition might provoke undefined
behaviour if the values are too large".

Oct 27 '07 #211
"Richard" <rg****@gmail.coma écrit dans le message de news:
gc************@news.individual.net...
"Charlie Gordon" <ne**@chqrlie.orgwrites:
>"Richard" <rg****@gmail.coma écrit dans le message de news:
56************@news.individual.net...
>>"Malcolm McLean" <re*******@btinternet.comwrites:

"santosh" <sa*********@gmail.comwrote in message
Malcolm McLean wrote:
>
>Which in fact is almost every integer.
>
Maybe this is true in the sort of programming you do, but there are
many
programs where integers are needed for arithmetic far more than
indexing.
>
I'm pretty sure that's a perception rather than a reality. Let's say
you are storing a list of amounts of money as integers. You write a
routine to take the average. When asked "what does this routine do"
you will answer "it adds up an amount of money, divides by the count,
and reports it."
Actually that's not what it does.

int average(int *money, size_t N)
{
size_t i;
int total = 0;

for(i=0;i<N;i++)
total += money[i];
return total/N;
}

Whilst there are two operations that operate on int (total =0, total
+=), there are four which operate on i, and one which operates on

No there are not. it depends what the compiler does. You could as easily
make it 1 one off for initilisation and one for the loop and check

int i=N;
while(i--)
total += money[i];

total and N. Whether you count C instructions or machine operations,
what the function is mainly doing is calculating a list of indices.

Its not mainly doing that at all. It is mainly accessing and adding up
numbers.

However the programmer's perception will be that he is mainly working
with amounts of money, because that is what is important to his
human-centric way of looking at the routine.

You confuse me by trying to think too much into it.

This function adds a set integers together and then returns the average.

That's what it attempts to do, but the calculation is quite likely to
cause
integer overflow if the array and/or values are large enough, causing

Its not quite likely to do anything of the sort if it is operating in
the limits the designer set - otherwise we would use different types.
>undefined behaviour. Otherwise, the result is the average of the values
of
the array, rounded towards zero. If the size N passed is zero, undefined
behaviour is invoked.

I'm not sure I understand why you are writing this. This applies to any
and all code posted here and a code review isn't the issue here.

Anytime someone posts a line like

x+=y;

One could make this comment "that addition might provoke undefined
behaviour if the values are too large".
It is a matter of common sense! Summing an array of unknown size is likely
to cause overflow: the programmer may well have been oblivious to this fact.
the array may contain large numbers, this way of computing the average
requires as a pre-condition that the sum be within bounds of an int type.
This condition is non obvious and should at least be stated in a comment.

Regarding the division by zero, it is a classic bug is this kind of
function. A simple test prevents undefined (and quite likely catastrophic)
behaviour for the case N == 0. Calling this function with N == 0 should be
allowed: N is the number of values to average, not necessarily the size of
the array.

I'm giving a code review for any code posted on c.l.c: I provide advice that
others find useful and informative. I try to use common sense and help
posters avoid classic mistakes. Sometimes it involves deterring them from
using certain problematic functions from the standard C library (strtok,
strncpy...), sometimes I try to help people write more readably, or use less
error prone constructs and algorithms. I think my criticism is on average
more constructive than yours.

--
Chqrlie.
Oct 27 '07 #212

"Richard" <rg****@gmail.comwrote in message
(average function)
Its not quite likely to do anything of the sort if it is operating in
the limits the designer set - otherwise we would use different types.
In reality we would use a floating point rather than an integer type. But
that wasn't the point I was trying to make.

--
Free games and programming goodies.
http://www.personal.leeds.ac.uk/~bgy1mm

Oct 27 '07 #213
"Malcolm McLean" <re*******@btinternet.comwrites:
"santosh" <sa*********@gmail.comwrote in message
>Malcolm McLean wrote:
>>Which in fact is almost every integer.

Maybe this is true in the sort of programming you do, but there are many
programs where integers are needed for arithmetic far more than
indexing.
I'm pretty sure that's a perception rather than a reality. Let's say
you are storing a list of amounts of money as integers. You write a
routine to take the average. When asked "what does this routine do"
you will answer "it adds up an amount of money, divides by the count,
and reports it."
Actually that's not what it does.

int average(int *money, size_t N)
{
size_t i;
int total = 0;

for(i=0;i<N;i++)
total += money[i];
return total/N;
}
[...]

Not all data is stored in arrays. Depending on the application, a
significant amount of data might be stored in, say, trees or linked
lists.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Oct 27 '07 #214
Charlie Gordon wrote, On 26/10/07 05:19:
"Flash Gordon" <sp**@flash-gordon.me.uka écrit dans le message de news:
64***********@news.flash-gordon.me.uk...
>Charlie Gordon wrote, On 20/10/07 13:54:
<snip>
>>strncpy can be banned with no downside.
Except where it is the right tool for the job. If an application developer
had made a slightly different choice, namely 0 padding instead of space
padding, on the application I spend a lot of time working on then it would
make *far* more calls to strncpy than calls strcpy. If I had the time I
would actually make that change to the SW.

I assume you wrote your own utility functions for space padded fixed width
non zero terminated char arrays. That was quite easy, was it not?
I didn't, the original developer did. I agree it was easy though.
If the application developper had made the slightly different choice of 0
padding, you would just as easily have written the appropriate utility
functions. IMHO, it would be far less confusing to newbie readers of your
code then to have used strncpy.
There is so much complexity in the code that use of strncpy would be the
least of a newbies problems.

I would use strncpy because it *might* be optimised by the
implementation, it gets called a significant amount (well, the
equivalent for what we actually use does) and we target several
different systems so optimising it ourselves could be a pain.

<snip stuff agreed with>
>If the answer was "yes" then I would say the risk was in erroneously using
it when the intent is to produce a C string rather than populate such a
fields and that naming conventions should be used to assist in spotting
correct vs incorrect usage. Further mitigation would include ensuring that
such limits are tested and the usual stuff about reviews and use of grep.

Using a specific function with a more appropriate name is a good start to
avoid the confusion strncpy is likely to bring along.
Well, in our own library header I suppose we could do
#define dbfieldcpy(dest,src,size) strncpy(dest,src,size)

Actually, since some of the code pre-dates the ANSI standard there was a
customer written implementation of what was effectively memmove
(although I found a bug in it) which I have replaced with just such a
#define.
>> Pointers are a fundamental feature of the language. The class of
problems that can be solved without them has a topological measure of
zero.
Not quite, there are *some* programs that can be written without pointers,
just not many.

The only standard way for a C program to do I/O is to rely on streams
provided by stdio.h, which make use of pointers. Same for command line
arguments: argv is an array of pointers. Actually all arrays convert to
pointers as soon as they are used in expressions (except as the operand to
sizeof).
A program that does not use pointers at all cannot take form of variable
input, and can only produce a return or exit code, namely EXIT_SUCCESS or
EXIT_FAILURE (or 0, but that may be the value of either of these).
There is still a wide variety of programs that can be written this way to
just produce a yes/no answer... but an infinitely small fraction of them
all.
A very useful couple of programs in unix are true and false. One returns
success the other returns failure and they do nothing else. These meet
all of the limitations you specify :-)
>>>FCOL, Tor. Wake up and smell the real risk - clueless programmers, hired
by
witless buffoons because they have good hair and a good CV.
90% of the IT work force. More than 90% of all code produced.
I've been fortunate and only worked with a few clueless programmers.

Ambiguous: only a few clueless and many smart ones, or did you restrict your
working environment to just a few programmers, all of them clueless, and
consider that fortunate ;-?
Only a few programmers I've worked with have been clueless, most have
been good or better.
--
Flash Gordon
Oct 28 '07 #215
On Wed, 24 Oct 2007 22:43:09 +0100, Malcolm McLean wrote:
Malcom McLean's containers were a hit.
Yes, but the containers are not the unit of shipping; they're simply a
package. They're not an int, they're a class containing ints and shorts.
Guess what? Such packages are very useful. As are the things they
contain. Yet for some reason you wish to do away with every sort of box,
skid, tub, tube, the lot, and only use the largest possible item, the
container.

This, needless to say, is ridiculous, and has no relation to the real
world.
Oct 28 '07 #216
Malcolm McLean wrote, On 27/10/07 20:37:
>
"Richard" <rg****@gmail.comwrote in message
(average function)
>Its not quite likely to do anything of the sort if it is operating in
the limits the designer set - otherwise we would use different types.
In reality we would use a floating point rather than an integer type.
But that wasn't the point I was trying to make.
On most financial work, and your example was talking about money, you
can only use a floating point number if all your numbers can be exactly
represented in the floating point type (in fact, there are often legal
requirements, such as having to pay people what was agreed and paying
the correct amount of tax). This is why a lot of financial SW uses
integer types, generally int where it will fit. Oh, and the SW often has
hundreds of simultaneous users in the environments I deal with and is IO
bound (disk IO to be specific even when using decent storage), so
doubling the size of the integers would massively and unacceptably slow
it down.

Others have pointed out enough errors in your response to my post so I
won't bother.
--
Flash Gordon
Oct 28 '07 #217
Flash Gordon <sp**@flash-gordon.me.ukwrites:
Oh, and the SW often has hundreds of simultaneous users in the
environments I deal with and is IO bound (disk IO to be
specific even when using decent storage), so doubling the size
of the integers would massively and unacceptably slow it down.
Your software is disk I/O *bandwidth* bound? You must be reading
or writing massive amounts of storage, then. My guess would have
been that it was disk I/O *latency* bound, in which case doubling
the size of the data wouldn't make much difference.
--
Ben Pfaff
http://benpfaff.org
Oct 28 '07 #218

"Ben Pfaff" <bl*@cs.stanford.eduwrote in message
news:87************@blp.benpfaff.org...
Flash Gordon <sp**@flash-gordon.me.ukwrites:
>Oh, and the SW often has hundreds of simultaneous users in the
environments I deal with and is IO bound (disk IO to be
specific even when using decent storage), so doubling the size
of the integers would massively and unacceptably slow it down.

Your software is disk I/O *bandwidth* bound? You must be reading
or writing massive amounts of storage, then. My guess would have
been that it was disk I/O *latency* bound, in which case doubling
the size of the data wouldn't make much difference.
Even in the very worst case you have to be incredibly unlucky to slow down
the program by more than 50%. (I was going to say "can't", but that's not
strictly true - you can construct a scenario in which you thrash the cache
by doubling int size). That might sound a lot to an electrical engineer, but
in software terms it really is on the boundary of a worthwhile
optimisation - if we're not doubling speed at least we aren't really
speeding things up.

However that represents the sever at peak capacity. But if it has got
hundreds of simultaneous users, how often is the system running at peak
capacity?

Doubling int sizes would doubtless have some impact on performace. But not
the sort that is being suggested. Then I don't believe that most of the
calculations are of amounts of money, anyway. I think the system spends most
of its time copying data from one location to another.

It could be farming out memory to disk, however. In which case doubling
memory take would have a significant impact. IO is still largely latency
bound, but the number of writes would double.

--
Free games and programming goodies.
http://www.personal.leeds.ac.uk/~bgy1mm

Oct 28 '07 #219
On Oct 28, 1:31 pm, "Charlie Gordon" <n...@chqrlie.orgwrote:
"Flash Gordon" <s...@flash-gordon.me.uka écrit dans le message de news:
ib5dv4xgne....@news.flash-gordon.me.uk...
Charlie Gordon wrote, On 26/10/07 05:19:
"Flash Gordon" <s...@flash-gordon.me.uka écrit dans le message de news:
64dpu4xlf....@news.flash-gordon.me.uk...
Charlie Gordon wrote, On 20/10/07 13:54:
...
>> Pointers are a fundamental feature of the language. The class of
problems that can be solved without them has a topological measure of
zero.
Not quite, there are *some* programs that can be written without
pointers, just not many.
The only standard way for a C program to do I/O is to rely on streams
provided by stdio.h, which make use of pointers. Same for command line
arguments: argv is an array of pointers. Actually all arrays convert to
pointers as soon as they are used in expressions (except as the operand
to sizeof).
A program that does not use pointers at all cannot take form of variable
input, and can only produce a return or exit code, namely EXIT_SUCCESSor
EXIT_FAILURE (or 0, but that may be the value of either of these).
There is still a wide variety of programs that can be written this wayto
just produce a yes/no answer... but an infinitely small fraction of them
all.
A very useful couple of programs in unix are true and false. One returns
success the other returns failure and they do nothing else. These meet all
of the limitations you specify :-)

The built-in shell versions seem to do nothing else indeed, but the stand
alone utilities parse a couple of command line options, impossible to do
without pointers. Try:

$ /bin/true --help
$ /bin/false --version
GNU extensions. The POSIX forms don't have command line options and
don't use streams.
...
Oct 28 '07 #220
"Malcolm McLean" <re*******@btinternet.comwrote:
"Ben Pfaff" <bl*@cs.stanford.eduwrote in message
"Malcolm McLean" <re*******@btinternet.comwrites:
Secondly it is called size_t. If I was supreme ruler of the universe I
could force everyone to use it, but I'm not, and there's just no way
you are going to get consistent usage of a type called "size_t" for an
index variable.
What's wrong with the name size_t?
The underscore is unacceptable in something so fundamental.
*Blink*

You go from strength to strength.

Richard
Oct 29 '07 #221
rl*@hoekstra-uitgeverij.nl (Richard Bos) writes:
"Malcolm McLean" <re*******@btinternet.comwrote:
>"Ben Pfaff" <bl*@cs.stanford.eduwrote in message
"Malcolm McLean" <re*******@btinternet.comwrites:

Secondly it is called size_t. If I was supreme ruler of the universe I
could force everyone to use it, but I'm not, and there's just no way
you are going to get consistent usage of a type called "size_t" for an
index variable.

What's wrong with the name size_t?
The underscore is unacceptable in something so fundamental.

*Blink*

You go from strength to strength.

Richard
Actually, FWIW, I "kind of" agree with him.

It's not the norm for the standard types. It is misnamed.

What does the _t mean? type? type?

So where is int_t etc?

Consistency.

I don't like it either for just that reason.
Oct 29 '07 #222
In article <pe************@news.individual.net>,
Richard <rg****@gmail.comwrote:
>What does the _t mean? type? type?

So where is int_t etc?
Well, that's historical reasons for you.

If you said "_t indicates type names created with typedef" you'd have
a rule slightly closer to consistency.

-- Richard
--
"Consideration shall be given to the need for as many as 32 characters
in some alphabets" - X3.4, 1963.
Oct 29 '07 #223
ri*****@cogsci.ed.ac.uk (Richard Tobin) writes:
In article <pe************@news.individual.net>,
Richard <rg****@gmail.comwrote:
>>What does the _t mean? type? type?

So where is int_t etc?

Well, that's historical reasons for you.
Yes, it was kind of rhetorical. But frankly, i agree with the other
poster. size_t is ugly despite its reasons.

Frankly I find this "use size_t" advice to be ridiculous most of the
time when its known that the array index is certainly a lot less than
the MAXINT or whatever it is.
>
If you said "_t indicates type names created with typedef" you'd have
a rule slightly closer to consistency.

-- Richard
Oct 29 '07 #224
In article <v2************@news.individual.net>,
Richard <rg****@gmail.comwrote:
>Frankly I find this "use size_t" advice to be ridiculous most of the
time when its known that the array index is certainly a lot less than
the MAXINT or whatever it is.
I quite agree. It makes sense to use size_t in libraries for generic
string-handling functions and the like, but if you've got an array of
employees or chess pieces then int is the natural choice.

-- Richard
--
"Consideration shall be given to the need for as many as 32 characters
in some alphabets" - X3.4, 1963.
Oct 29 '07 #225
On Sat, 27 Oct 2007 20:37:02 +0100, Malcolm McLean wrote:
"Richard" <rg****@gmail.comwrote in message
(average function)
>Its not quite likely to do anything of the sort if it is operating in
the limits the designer set - otherwise we would use different types.
In reality we would use a floating point rather than an integer type.
For *monetary* calculations? Remind me never to use any of your stuff to
balance the checkbooks.
Oct 29 '07 #226
Richard <rg****@gmail.comwrites:
Frankly I find this "use size_t" advice to be ridiculous most of the
time when its known that the array index is certainly a lot less than
the MAXINT or whatever it is.
Yes, but has anyone actually advised size_t in a case when the array
index is certainly known to be less than INT_MAX?

Another worry is that things one knows to true with certainty about
some code today can be false tomorrow. Someone (I think is was Keith
Thompson) said they "got nervous" about certain constructs (it was bit
operations on signed types) and I thought how useful it is to have a
well developed sense of nervousness in C. 'int' indexes make me a
little nervous. Not a lot, a little.

The '_t' is a bit ugly but what should the committee have done? I've
not seen a good alternative. Malcolm McLean's idea of 64-bit int
everywhere has the wrong cost/benefit profile. The benefits of
liberal use of size_t far outweigh the costs.

--
Ben.
Oct 29 '07 #227
Ben Bacarisse <be********@bsb.me.ukwrites:
[...]
The '_t' is a bit ugly but what should the committee have done? I've
not seen a good alternative. Malcolm McLean's idea of 64-bit int
everywhere has the wrong cost/benefit profile. The benefits of
liberal use of size_t far outweigh the costs.
And there are plenty of other types whose names have the _t suffix:
time_t, int32_t, wchar_t, ptrdiff_t, fpos_t.

If you don't like the "_t" suffix, I'm afraid you're just going to
have to find a different language.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Oct 29 '07 #228
ri*****@cogsci.ed.ac.uk (Richard Tobin) writes:
In article <v2************@news.individual.net>,
Richard <rg****@gmail.comwrote:
>>Frankly I find this "use size_t" advice to be ridiculous most of the
time when its known that the array index is certainly a lot less than
the MAXINT or whatever it is.

I quite agree. It makes sense to use size_t in libraries for generic
string-handling functions and the like, but if you've got an array of
employees or chess pieces then int is the natural choice.
My current employer, the University of California, has more than 32767
employees (and my employee number requires at least 20 bits).

Granted you're not likely to be running software that deals with UC
employees on a 16-bit system (though I'm sure it was done in the
past), but you still need to be careful about your assumptions.

Perhaps if size_t had been called count_t, and described as a type
capable of holding counts of objects, there won't be so many
complaints about it.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
San Diego Supercomputer Center <* <http://users.sdsc.edu/~kst>
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Oct 29 '07 #229
Dann Corbit wrote:
Flash Gordon" <sp**@flash-gordon.me.ukwrote in message
[...]
>Increasing the number of reads and writes by 10% would be unpopular unless
it brought some other massive benefit, and your proposed change would not
provide my customers with any benefit, only costs.

I suspect that MonetDB may be helpful for your application.
Frequently, read based problems have a huge benefit from in-memory column
storage (e.g. 10-100x faster).
You would need at least one machine with large memory, though.
I rather suspect, nobody would really want to replace their financial
DB2 or Nonstop DB systems. Changing the DB infrastructure on a
business-critical system, could be very expensive.

Performance requirements might be important, but correctness, risk,
fault-tolerance, disaster-recovery, scalability, fail-over-time etc. are
typically more important, at least if Gordon is not talking about some
back-office system, but rather an online transaction environment, like
e.g. a stock-exchange or an EFTPOS host.

There is no simple answers to tuning such high-integrity systems, and
the usual lesson apply, first perform measurement to identify the
bottlenecks. If no benefits, don't do it.

--
Tor <bw****@wvtqvm.vw | tr i-za-h a-z>

"C gives you enough rope to hang yourself. C++ also gives you the tree
object to tie it to"
Oct 29 '07 #230
On Oct 29, 4:50 pm, Tor Rustad <tor_rus...@hotmail.comwrote:
Dann Corbit wrote:
Flash Gordon" <s...@flash-gordon.me.ukwrote in message

[...]
Increasing the number of reads and writes by 10% would be unpopular unless
it brought some other massive benefit, and your proposed change would not
provide my customers with any benefit, only costs.
I suspect that MonetDB may be helpful for your application.
Frequently, read based problems have a huge benefit from in-memory column
storage (e.g. 10-100x faster).
You would need at least one machine with large memory, though.

I rather suspect, nobody would really want to replace their financial
DB2 or Nonstop DB systems. Changing the DB infrastructure on a
business-critical system, could be very expensive.

Performance requirements might be important, but correctness, risk,
fault-tolerance, disaster-recovery, scalability, fail-over-time etc. are
typically more important, at least if Gordon is not talking about some
back-office system, but rather an online transaction environment, like
e.g. a stock-exchange or an EFTPOS host.

There is no simple answers to tuning such high-integrity systems, and
the usual lesson apply, first perform measurement to identify the
bottlenecks. If no benefits, don't do it.
I am not suggesting a replacement. I am suggesing a tool for OLAP.

Oct 30 '07 #231
Larry__Weiss wrote On 10/29/07 22:14,:
[...]
Many common tax return computations use floating point calculations (at
least for U.S. income taxes).

Sales taxes are usually done as a percentage of an amount.
Sales taxes are usually *stated* as a percentage
but *computed* by table-lookup.

--
Er*********@sun.com
Oct 30 '07 #232
On Tue, 30 Oct 2007 11:06:51 -0400, Eric Sosman <Er*********@sun.com>
wrote:
>Larry__Weiss wrote On 10/29/07 22:14,:
>[...]
Many common tax return computations use floating point calculations (at
least for U.S. income taxes).

Sales taxes are usually done as a percentage of an amount.

Sales taxes are usually *stated* as a percentage
but *computed* by table-lookup.
Not in our software. Given the fact that we handle multiple tax rates
in multiple taxing jurisdictions, there would be an awful lot of
tables.

--
Al Balmer
Sun City, AZ
Oct 30 '07 #233

"Ben Bacarisse" <be********@bsb.me.ukwrote in message
Yes, but has anyone actually advised size_t in a case when the array
index is certainly known to be less than INT_MAX?
I have. The problem is that a lot of arrays are unbounded but must be quite
small. It's quite hard to say what is the maximum number of children in a
class, for instance, but 255 is unmanageable.
The temptation is to use int for Nchildren. However you'll soon create a
situation where you've got a mix of signed and unsigned, int and size_t, and
you've got to juggle two types. It's manageable until you need to pass
indices by indirection, then all of a sudden the system gums up.
>
The '_t' is a bit ugly but what should the committee have done? I've
not seen a good alternative.
It should have realised that it wasn't fixing up a little problem with
malloc(). It was making a fundamental change to the language. Very few
size_t's hold sizes in terms of bytes of memory.

--
Free games and programming goodies.
http://www.personal.leeds.ac.uk/~bgy1mm

Oct 30 '07 #234
"Richard Heathfield" <rj*@see.sig.invalidwrote in message
Malcolm McLean said:

<snip>
>if we're not doubling speed at least we aren't really speeding things up.

Wrong. I can cite a 20% reduction in run-time in a (fairly hefty) program
that had taken 25 seconds to produce one particular kind of quotation.
Another case is interactive graphics. It doesn't matter how long your
calculation takes as long as you make the next frame. If you miss it by a
few microseconds, you've got all of 17 millseconds to play with until the
next one come along.

However generally I regard a 100% speedup as about the threshold for code
worth my time optimising.

--
Free games and programming goodies.
http://www.personal.leeds.ac.uk/~bgy1mm

Oct 30 '07 #235
user923005 wrote:

[...]
I am not suggesting a replacement. I am suggesing a tool for OLAP.
OK, I assumed the financial system in question, rather was OLTP.

--
Tor <bw****@wvtqvm.vw | tr i-za-h a-z>
Oct 30 '07 #236
Tor Rustad said:
Richard Heathfield wrote:
>Tor Rustad said:
<snip>
>>>
Furthermore, many of the calculations needed for double entry
bookeeping, can be done exactly by banks.

Why "many" rather than "all"? Since double-entry book-keeping is a way
of recording financial transactions (i.e. transfers of an exact integer
number of base currency units, e.g. pennies, cents, pesos or whatever),
I'm struggling to imagine any real-world double-entry-relevant
calculation that /cannot/ be done exactly. Even if the numbers involved
are colossal, they can still be processed exactly. You might need a
bignum lib to do it, but you *can* do it.

What if the currency of the transaction, is different from the currency
of the account?
I think you'll find that the banks fudge the amount so that it comes to a
whole number of pennies/cents/whatever.
We still have only one currency here, but e.g. UK banks could perhaps
accept transactions in Euro's too? How was the transition to Euro done
in France, Germany etc?
Badly, it seems. In 1997, 1 Euro was supposed to be worth around 73p, and
it's currently only worth about 69p, so it's dropped by about 5.5% over 10
years.

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Nov 2 '07 #237
On Nov 2, 10:37 pm, Richard Heathfield <r...@see.sig.invalidwrote:
Badly, it seems. In 1997, 1 Euro was supposed to be worth around 73p, and
it's currently only worth about 69p, so it's dropped by about 5.5% over 10
years.
More accurately, both currencies have declined in value (due to
inflation) but the Euro has depreciated more rapidly than the Pound
since 1997.
>
--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999

Nov 2 '07 #238
Richard Heathfield wrote:
Tor Rustad said:
>Richard Heathfield wrote:
>>Tor Rustad said:
<snip>
>>>Furthermore, many of the calculations needed for double entry
bookeeping, can be done exactly by banks.
Why "many" rather than "all"? Since double-entry book-keeping is a way
of recording financial transactions (i.e. transfers of an exact integer
number of base currency units, e.g. pennies, cents, pesos or whatever),
I'm struggling to imagine any real-world double-entry-relevant
calculation that /cannot/ be done exactly. Even if the numbers involved
are colossal, they can still be processed exactly. You might need a
bignum lib to do it, but you *can* do it.
What if the currency of the transaction, is different from the currency
of the account?

I think you'll find that the banks fudge the amount so that it comes to a
whole number of pennies/cents/whatever.
I don't know what "fudge" means, but I assume you still argue your
point, as you always do! :)

I expect, account transfers in e.g. UK these days, to be available
between sterling and euro accounts, and such conversion could result in
rounding. That's the reason I wrote *many*, and not *all*.

I'm right, or I'm right?

--
Tor <bw****@wvtqvm.vw | tr i-za-h a-z>
Nov 2 '07 #239
Tor Rustad said:
Richard Heathfield wrote:
>Tor Rustad said:
>>Richard Heathfield wrote:
Tor Rustad said:
<snip>
>>>>Furthermore, many of the calculations needed for double entry
bookeeping, can be done exactly by banks.
Why "many" rather than "all"? Since double-entry book-keeping is a way
of recording financial transactions (i.e. transfers of an exact
integer number of base currency units, e.g. pennies, cents, pesos or
whatever), I'm struggling to imagine any real-world
double-entry-relevant calculation that /cannot/ be done exactly. Even
if the numbers involved are colossal, they can still be processed
exactly. You might need a bignum lib to do it, but you *can* do it.
What if the currency of the transaction, is different from the currency
of the account?

I think you'll find that the banks fudge the amount so that it comes to
a whole number of pennies/cents/whatever.

I don't know what "fudge" means,
fiddle, tweak, finagle, frob...
but I assume you still argue your
point, as you always do! :)
Well, it's funny you should say that, because I'm going to stop arguing it
here. "I think you'll find" means precisely that - i.e. what I've said is
what I think happens, but I could certainly be wrong.
I expect, account transfers in e.g. UK these days, to be available
between sterling and euro accounts, and such conversion could result in
rounding. That's the reason I wrote *many*, and not *all*.

I'm right, or I'm right?
I don't know whether or not you are right. I suspect that you're mistaken,
but I could easily be wrong.

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Nov 2 '07 #240
Fr************@googlemail.com wrote:
On Nov 2, 10:37 pm, Richard Heathfield <r...@see.sig.invalidwrote:
>Badly, it seems. In 1997, 1 Euro was supposed to be worth around 73p, and
it's currently only worth about 69p, so it's dropped by about 5.5% over 10
years.

More accurately, both currencies have declined in value (due to
inflation) but the Euro has depreciated more rapidly than the Pound
since 1997.
The Euro and the Pound have declined against what? The Pound buys
US$2.08 now. The Euro buys $1.45 or so. They seem strong against the dollar.

--
Joe Wright
"Everything should be made as simple as possible, but not simpler."
--- Albert Einstein ---
Nov 3 '07 #241

"Richard Heathfield" <rj*@see.sig.invalidwrote in message
news:Xt******************************@bt.com...
Tor Rustad said:
>What if the currency of the transaction, is different from the currency
of the account?

I think you'll find that the banks fudge the amount so that it comes to a
whole number of pennies/cents/whatever.

Badly, it seems. In 1997, 1 Euro was supposed to be worth around 73p,
and it's currently only worth about 69p, so it's dropped by about 5.5%
over
10 years.
1 Euro isn't worth 69p. If you can trade it at all you'd probably get more
like 50p for it. Trade thousands of Euros and you'll be able to get better
terms.

That's the answer to Tor's question. A bank cannot covert 100 Euros to 69
pounds 21.23456p applying the exchange rate. It's got to trade those Euros
with someone who has pounds. And it will settle on a whole number of
pennies.
--
Free games and programming goodies.
http://www.personal.leeds.ac.uk/~bgy1mm

Nov 3 '07 #242
Malcolm McLean wrote, On 03/11/07 07:13:
>
"Richard Heathfield" <rj*@see.sig.invalidwrote in message
news:Xt******************************@bt.com...
>Tor Rustad said:
>>What if the currency of the transaction, is different from the currency
of the account?

I think you'll find that the banks fudge the amount so that it comes to a
whole number of pennies/cents/whatever.

Badly, it seems. In 1997, 1 Euro was supposed to be worth around 73p,
and it's currently only worth about 69p, so it's dropped by about
5.5% over
10 years.
1 Euro isn't worth 69p. If you can trade it at all you'd probably get
more like 50p for it. Trade thousands of Euros and you'll be able to get
better terms.

That's the answer to Tor's question. A bank cannot covert 100 Euros to
69 pounds 21.23456p applying the exchange rate. It's got to trade those
Euros with someone who has pounds. And it will settle on a whole number
of pennies.
Similarly with all other transactions and accounting practices that I am
aware of. You are always *required* to round (either up to, down to or
to the nearest) whole whatever. The exact rounding rules change
depending on what you are doing, but they are always exactly specified.

Oh, and in our multi-currency system we store the amount in the original
currency and the exchange rate on each transaction so we can do exact
calculation in originating currency and correctly rounded calculations
in the target currency. This adds a whole load more integer calculations
on money to the SW.
--
Flash Gordon
Nov 3 '07 #243
Richard Heathfield wrote:
Tor Rustad said:
>Richard Heathfield wrote:
>>Tor Rustad said:

Richard Heathfield wrote:
Tor Rustad said:
>
<snip>
>Furthermore, many of the calculations needed for double entry
>bookeeping, can be done exactly by banks.
Why "many" rather than "all"? Since double-entry book-keeping is a way
of recording financial transactions (i.e. transfers of an exact
integer number of base currency units, e.g. pennies, cents, pesos or
whatever), I'm struggling to imagine any real-world
double-entry-relevant calculation that /cannot/ be done exactly. Even
if the numbers involved are colossal, they can still be processed
exactly. You might need a bignum lib to do it, but you *can* do it.
What if the currency of the transaction, is different from the currency
of the account?
I think you'll find that the banks fudge the amount so that it comes to
a whole number of pennies/cents/whatever.
I don't know what "fudge" means,

fiddle, tweak, finagle, frob...
So, you talked about *rounding*. :)

FYI, calculations using rounding, are not done *exactly*.

--
Tor <bw****@wvtqvm.vw | tr i-za-h a-z>
Nov 3 '07 #244
On Nov 3, 12:09 am, Joe Wright <joewwri...@comcast.netwrote:
Francine.Ne...@googlemail.com wrote:
More accurately, both currencies have declined in value (due to
inflation) but the Euro has depreciated more rapidly than the Pound
since 1997.

The Euro and the Pound have declined against what? The Pound buys
US$2.08 now. The Euro buys $1.45 or so. They seem strong against the dollar.
They have declined absolutely. Money is worth what you can buy with
it, and a Pound today buys you less stuff than a Pound did in 1997.
(Similarly with a Euro, had there been any actual Euros in 1997.) Your
observation is that the Dollar has declined more rapidly than the
Pound and the Euro in that time.
>
--
Joe Wright
"Everything should be made as simple as possible, but not simpler."
--- Albert Einstein ---
Nov 3 '07 #245

"Flash Gordon" <sp**@flash-gordon.me.ukwrote in message
Malcolm McLean wrote, On 03/11/07 07:13:
>>
"Richard Heathfield" <rj*@see.sig.invalidwrote in message
news:Xt******************************@bt.com...
>>Tor Rustad said:

What if the currency of the transaction, is different from the currency
of the account?

I think you'll find that the banks fudge the amount so that it comes to
a
whole number of pennies/cents/whatever.

Badly, it seems. In 1997, 1 Euro was supposed to be worth around 73p,
and it's currently only worth about 69p, so it's dropped by about 5.5%
over
10 years.
1 Euro isn't worth 69p. If you can trade it at all you'd probably get
more like 50p for it. Trade thousands of Euros and you'll be able to get
better terms.

That's the answer to Tor's question. A bank cannot covert 100 Euros to 69
pounds 21.23456p applying the exchange rate. It's got to trade those
Euros with someone who has pounds. And it will settle on a whole number
of pennies.

Similarly with all other transactions and accounting practices that I am
aware of. You are always *required* to round (either up to, down to or to
the nearest) whole whatever. The exact rounding rules change depending on
what you are doing, but they are always exactly specified.

Oh, and in our multi-currency system we store the amount in the original
currency and the exchange rate on each transaction so we can do exact
calculation in originating currency and correctly rounded calculations in
the target currency. This adds a whole load more integer calculations on
money to the SW.
You can use a double to hold integers. It has got several advantages, such
as being able to hold more digits of precision than a 32 bit type, degrading
gracefully under hyperinflation - it will no longer give exact results, of
course, but if there are 6 trillion dollars to the pound that will be the
least of any American's worries - and giving you a free check that rounding
has actually been applied.

--
Free games and programming goodies.
http://www.personal.leeds.ac.uk/~bgy1mm

Nov 3 '07 #246
"Malcolm McLean" <re*******@btinternet.comwrites:
[...]
You can use a double to hold integers. It has got several advantages,
such as being able to hold more digits of precision than a 32 bit
type, degrading gracefully under hyperinflation - it will no longer
give exact results, of course, but if there are 6 trillion dollars to
the pound that will be the least of any American's worries - and
giving you a free check that rounding has actually been applied.
As I understand it, inexact results in monetary calculations are
*never* acceptable. Using a floating-point type might give you an
acceptable range over which exact values can be represented, but if
you go outside that range you *silently* get inexact results.

In a typical modern implementation, both double and long long are 64
bits -- but long long doesn't waste bits on an exponent, and can
therefore represent a much wider range of integer values exactly.
Many implementations that don't support long long nevertheless support
a 64-bit integer type by another name.

--
Keith Thompson (The_Other_Keith) ks***@mib.org <http://www.ghoti.net/~kst>
Looking for software development work in the San Diego area.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
Nov 3 '07 #247
Tor Rustad said:
Richard Heathfield wrote:
>Tor Rustad said:
>>Richard Heathfield wrote:
Tor Rustad said:
Richard Heathfield wrote:
>Tor Rustad said:
>>
<snip>
>>Furthermore, many of the calculations needed for double entry
>>bookeeping, can be done exactly by banks.
>[...] I'm struggling to imagine any real-world
>double-entry-relevant calculation that /cannot/ be done exactly.
>Even if the numbers involved are colossal, they can still be
>processed exactly. You might need a bignum lib to do it, but you
>*can* do it.
What if the currency of the transaction, is different from the
currency
of the account?
<snip>
>
So, you talked about *rounding*. :)

FYI, calculations using rounding, are not done *exactly*.
Fine, but we're actually talking about different things. I'm talking about
"calculations needed for double entry bookkeeping". You are talking about
"calculations needed for currency conversion". These are two different
ideas.

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
"Usenet is a strange place" - dmr 29 July 1999
Nov 3 '07 #248

"Keith Thompson" <ks***@mib.orgwrote in message
Hyperinflation is unlikely to cause amounts of money to exceed 2**64-1
(about 18 quintillion). Even if it did, the response would almost
certainly be to issue a new devalued currency (one new dollar equal to
one trillion old dollars, for example).
The Eurpean Central bank pumped in 400 billions of Euros of liquidity last
August. There are about 650 billion Euros of currency in circulation. They
are hoping that most of that 400 billion will come back in before anyone
demands it in cash, however assuming that the full amount is taken up, they
will need to pump in about 600 billion to have the same effect next time.
Then it will be 1 trillion. Printing money is O(N^2). Pull that trick more
than a few times and you'll get up to 18 quintillion remarkably quickly.

--
Free games and programming goodies.
http://www.personal.leeds.ac.uk/~bgy1mm

Nov 3 '07 #249
Richard Heathfield wrote:
Tor Rustad said:
>Richard Heathfield wrote:
>>Tor Rustad said:
Richard Heathfield wrote:
Tor Rustad said:
>Richard Heathfield wrote:
>>Tor Rustad said:
>>>
<snip>
>>>Furthermore, many of the calculations needed for double entry
>>>bookeeping, can be done exactly by banks.
>>[...] I'm struggling to imagine any real-world
>>double-entry-relevant calculation that /cannot/ be done exactly.
>>Even if the numbers involved are colossal, they can still be
>>processed exactly. You might need a bignum lib to do it, but you
>>*can* do it.
>What if the currency of the transaction, is different from the
>currency
> of the account?
<snip>
>So, you talked about *rounding*. :)

FYI, calculations using rounding, are not done *exactly*.

Fine, but we're actually talking about different things. I'm talking about
"calculations needed for double entry bookkeeping". You are talking about
"calculations needed for currency conversion". These are two different
ideas.
Methinks, you initially only considered single currency. :)

--
Tor <bw****@wvtqvm.vw | tr i-za-h a-z>
Nov 3 '07 #250

This thread has been closed and replies have been disabled. Please start a new discussion.

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.