rounding up (or down) issue

rounding up (or down) issue

am 19.12.2007 17:32:09 von Farid Hamjavar

Greetings,

I have data lines in a file like these whose
components add up to 100:

1.73 0.45 98.72
1.88 23.11 75.01
16.88 0.88 82.24



Yet, when attempting to round down (or up)
resulting data will not be 100 in total:

e.g. 2nd row , rounded up:
2 24 75 = 101

e.g. 2nd row , rounded down:
1 23 75 = 99


I need to round them up (or down) for reporting
purpose in which the line show up like:

2% 24% 75% = 101%



How does one get round this?
i.e. Any way to get 100 after rounding up (or down)?


Thanks,
Farid

Re: rounding up (or down) issue

am 19.12.2007 18:04:02 von Janis Papanagnou

Farid Hamjavar wrote:
> Greetings,
>
> I have data lines in a file like these whose
> components add up to 100:
>
> 1.73 0.45 98.72
> 1.88 23.11 75.01
> 16.88 0.88 82.24
>
>
>
> Yet, when attempting to round down (or up)
> resulting data will not be 100 in total:
>
> e.g. 2nd row , rounded up:
> 2 24 75 = 101
>
> e.g. 2nd row , rounded down:
> 1 23 75 = 99
>
>
> I need to round them up (or down) for reporting
> purpose in which the line show up like:
>
> 2% 24% 75% = 101%
>
>
>
> How does one get round this?

The (quite) most accurate way is to round arithmetically

round(x) = floor(x+0.5)

where floor() is trucation to the integral part. There
have been improvements suggested that are slightly better
than that; they consider whether specific digits are even
or odd to decide whether to round up or down in the case
that a value has exactly a least significant digit of 5,
otherwise it's rounded arithmetically. (I think that has
been mentioned in a paper called "What computer scientists
should know about floating point numbers." or so.) Anyway,
you'll always find numbers that won't fit.

> i.e. Any way to get 100 after rounding up (or down)?

No, that's in general not possible. If, as you do, reduce
precision and then add the numbers you'll not get what you
would like to have.

Janis

>
>
> Thanks,
> Farid
>
>

Re: rounding up (or down) issue

am 19.12.2007 20:34:46 von Bill Marcum

["Followup-To:" header set to comp.unix.shell.]
On 2007-12-19, Farid Hamjavar wrote:
>
>
>
> Greetings,
>
> I have data lines in a file like these whose
> components add up to 100:
>
> 1.73 0.45 98.72
> 1.88 23.11 75.01
> 16.88 0.88 82.24
>
>
>
> Yet, when attempting to round down (or up)
> resulting data will not be 100 in total:
>
> e.g. 2nd row , rounded up:
> 2 24 75 = 101
>
> e.g. 2nd row , rounded down:
> 1 23 75 = 99
>
>
> I need to round them up (or down) for reporting
> purpose in which the line show up like:
>
> 2% 24% 75% = 101%
>
>
>
> How does one get round this?
> i.e. Any way to get 100 after rounding up (or down)?
>
Round the sums after you add them, not before.

Re: rounding up (or down) issue

am 19.12.2007 20:35:09 von Rikishi 42

On 2007-12-19, Janis Papanagnou wrote:
>> I have data lines in a file like these whose
>> components add up to 100:
>>
>> 1.73 0.45 98.72
>> 1.88 23.11 75.01
>> 16.88 0.88 82.24
>>
>> I need to round them up (or down) for reporting
>> purpose in which the line show up like:
>>
>> 2% 24% 75% = 101%
>>
> The (quite) most accurate way is to round arithmetically
>
> round(x) = floor(x+0.5)
>
> where floor() is trucation to the integral part. There
> have been improvements suggested that are slightly better
> than that; they consider whether specific digits are even
> or odd to decide whether to round up or down in the case
> that a value has exactly a least significant digit of 5,
> otherwise it's rounded arithmetically. (I think that has
> been mentioned in a paper called "What computer scientists
> should know about floating point numbers." or so.) Anyway,
> you'll always find numbers that won't fit.
>
>> i.e. Any way to get 100 after rounding up (or down)?
>
> No, that's in general not possible. If, as you do, reduce
> precision and then add the numbers you'll not get what you
> would like to have.


A question to the OP: the 3 example rows have a rather larger third value.
Is that just random, or would that value be something like the remainder,
the eftover value? Is it allways much larger than the first 2 ?

If so, you could round the first 2, according to the usual (above) rule. You
could sthen ubstract the first 2 from 100, to obtain number 3.
100% -2% -24% = 74%

It's still wrong to do this, because it will be poorly rounded. But you'll
have a coherent display and it'll impact less for a large number, than for a
File /home/werner/.followup saved.


I'd just display 2 digits after the decimal point in the percentage.
But won't get you 100.00, mind you.

--
There is an art, it says, or rather, a knack to flying.
The knack lies in learning how to throw yourself at the ground and miss.
Douglas Adams

Re: rounding up (or down) issue

am 20.12.2007 06:40:14 von Ed Morton

On 12/19/2007 10:32 AM, Farid Hamjavar wrote:
> Greetings,
>
> I have data lines in a file like these whose
> components add up to 100:
>
> 1.73 0.45 98.72
> 1.88 23.11 75.01
> 16.88 0.88 82.24
>
>
>
> Yet, when attempting to round down (or up)
> resulting data will not be 100 in total:
>
> e.g. 2nd row , rounded up:
> 2 24 75 = 101
>
> e.g. 2nd row , rounded down:
> 1 23 75 = 99
>
>
> I need to round them up (or down) for reporting
> purpose in which the line show up like:
>
> 2% 24% 75% = 101%
>
>
>
> How does one get round this?
> i.e. Any way to get 100 after rounding up (or down)?
>

Getting 100 isn't the problem:

$ cat file
1.73 0.45 98.72
1.88 23.11 75.01
16.88 0.88 82.24

$ awk '{printf "%d\n", $1+$2+$3}' file
100
100
100

It's getting intermediate values that add up to 100 that's the problem:

$ awk '{printf "%d+%d+%d=%d\n",$1,$2,$3, $1+$2+$3}' file
1+0+98=100
1+23+75=100
16+0+82=100

Would it be acceptable to determine the total, round all but the largest value
however you like, and then subtract their sub-total from the real total to give
a replacement for the "rounded largest value"? e.g. something like this:

$ cat approx.awk
{
tot=maxVal=subTot=0
for (i=1;i<=NF;i++) {
if ($i > maxVal) {
maxVal = $i
maxFld = i
}
tot += $i
$i = int($i)
}

for (i=1;i<=NF;i++) {
if (i != maxFld) {
subTot += $i
}
}

$maxFld = tot - subTot

sep=""
for (i=1;i<=NF;i++) {
printf "%s%d",sep,$i
sep="+"
}
printf "=%d\n",tot
}

$ awk -f approx.awk file
1+0+99=100
1+23+76=100
16+0+84=100

Regards,

Ed.

Re: rounding up (or down) issue

am 20.12.2007 06:53:33 von Ed Morton

On 12/19/2007 11:40 PM, Ed Morton wrote:
>
> On 12/19/2007 10:32 AM, Farid Hamjavar wrote:
>
>>Greetings,
>>
>>I have data lines in a file like these whose
>>components add up to 100:
>>
>>1.73 0.45 98.72
>>1.88 23.11 75.01
>>16.88 0.88 82.24
>>
>>
>>
>>Yet, when attempting to round down (or up)
>>resulting data will not be 100 in total:
>>
>>e.g. 2nd row , rounded up:
>>2 24 75 = 101
>>
>>e.g. 2nd row , rounded down:
>>1 23 75 = 99
>>
>>
>>I need to round them up (or down) for reporting
>>purpose in which the line show up like:
>>
>>2% 24% 75% = 101%
>>
>>
>>
>>How does one get round this?
>>i.e. Any way to get 100 after rounding up (or down)?
>>
>
>
> Getting 100 isn't the problem:
>
> $ cat file
> 1.73 0.45 98.72
> 1.88 23.11 75.01
> 16.88 0.88 82.24
>
> $ awk '{printf "%d\n", $1+$2+$3}' file
> 100
> 100
> 100
>
> It's getting intermediate values that add up to 100 that's the problem:
>
> $ awk '{printf "%d+%d+%d=%d\n",$1,$2,$3, $1+$2+$3}' file
> 1+0+98=100
> 1+23+75=100
> 16+0+82=100
>
> Would it be acceptable to determine the total, round all but the largest value
> however you like, and then subtract their sub-total from the real total to give
> a replacement for the "rounded largest value"? e.g. something like this:

Fixed for better accuracy after seeing "round()" in Janis's earlier post:

$ cat approx.awk
{
tot=maxVal=subTot=0
for (i=1;i<=NF;i++) {
if ($i > maxVal) {
maxVal = $i
maxFld = i
}
tot += $i
$i = int($i+0.5)
}

for (i=1;i<=NF;i++) {
if (i != maxFld) {
subTot += $i
}
}

$maxFld = tot - subTot

sep=""
for (i=1;i<=NF;i++) {
printf "%s%d",sep,$i
sep="+"
}
printf "=%d\n",tot
}

$ awk -f approx.awk file
2+0+98=100
2+23+75=100
17+1+82=100

Regards,

Ed.