user/4940: bc doesn't work correctly with binary fractions

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

user/4940: bc doesn't work correctly with binary fractions

Zvezdan Petkovic
>Number:         4940
>Category:       user
>Synopsis:       binary fractional numbers
>Confidential:   yes
>Severity:       serious
>Priority:       medium
>Responsible:    bugs
>State:          open
>Quarter:        
>Keywords:      
>Date-Required:
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Tue Dec 13 08:50:01 GMT 2005
>Closed-Date:
>Last-Modified:
>Originator:     Zvezdan Petkovic
>Release:        OPENBSD_3_8
>Organization:
net
>Environment:
       
        System      : OpenBSD 3.8
        Architecture: OpenBSD.i386
        Machine     : i386
>Description:
       
        bc doesn't know how to work with binary fractions.
        Results do not make any sense at all.
>How-To-Repeat:
       
        $ bc
        ibase=2
        obase=2
        scale=10111
        1.1011 * 1.11
        .00000000000011000110

        This result is a total nonsense.

        The correct result produced with HP-UX bc (Linux bc gives the
        same result, as well as manual calculation):

        $ bc
        ibase=2
        obase=2
        scale=10111
        1.1011 * 1.11
        10.1111010000000000000

>Fix:


>Release-Note:
>Audit-Trail:
>Unformatted:

Reply | Threaded
Open this post in threaded view
|

Re: user/4940: bc doesn't work correctly with binary fractions

Otto Moerbeek
The following reply was made to PR user/4940; it has been noted by GNATS.

From: Otto Moerbeek <[hidden email]>
To: [hidden email]
Cc: [hidden email]
Subject: Re: user/4940: bc doesn't work correctly with binary fractions
Date: Tue, 13 Dec 2005 11:21:47 +0100 (CET)

 On Tue, 13 Dec 2005, [hidden email] wrote:
 
 The input routine for fractions with non-decimal base is broken.
 
 The actual computation is done correctly if decimal input and binary
 output is used.
 
 
 [otto@fonzo:1]$ bc
 obase=2
 scale=23
 1.6875 * 1.75
 10.11110100000000000000
 
 It just seem to have overlooked non-decimal fractions when writing the
 input routine.  I'll try to make a fix in the coming days.
 
  -Otto

Reply | Threaded
Open this post in threaded view
|

Re: user/4940: bc doesn't work correctly with binary fractions

Otto Moerbeek
In reply to this post by Zvezdan Petkovic
The following reply was made to PR user/4940; it has been noted by GNATS.

From: Otto Moerbeek <[hidden email]>
To: [hidden email]
Cc: [hidden email]
Subject: Re: user/4940: bc doesn't work correctly with binary fractions
Date: Tue, 13 Dec 2005 12:37:03 +0100 (CET)

 On Tue, 13 Dec 2005, Otto Moerbeek wrote:
 
 > The following reply was made to PR user/4940; it has been noted by GNATS.
 >
 > From: Otto Moerbeek <[hidden email]>
 > To: [hidden email]
 > Cc: [hidden email]
 > Subject: Re: user/4940: bc doesn't work correctly with binary fractions
 > Date: Tue, 13 Dec 2005 11:21:47 +0100 (CET)
 >
 >  On Tue, 13 Dec 2005, [hidden email] wrote:
 >  
 >  The input routine for fractions with non-decimal base is broken.
 >  
 >  The actual computation is done correctly if decimal input and binary
 >  output is used.
 >  
 >  
 >  [otto@fonzo:1]$ bc
 >  obase=2
 >  scale=23
 >  1.6875 * 1.75
 >  10.11110100000000000000
 >  
 >  It just seem to have overlooked non-decimal fractions when writing the
 >  input routine.  I'll try to make a fix in the coming days.
 
 This might be the right fix.
 
  -Otto
 
 Index: inout.c
 ===================================================================
 RCS file: /cvs/src/usr.bin/dc/inout.c,v
 retrieving revision 1.12
 diff -u -p -r1.12 inout.c
 --- inout.c 29 Mar 2005 10:53:54 -0000 1.12
 +++ inout.c 13 Dec 2005 11:34:23 -0000
 @@ -192,6 +192,7 @@ readnumber(struct source *src, u_int bas
  bool sign = false;
  bool dot = false;
  BN_ULONG v;
 + u_int i;
 
  n = new_number();
  bn_check(BN_zero(n->number));
 @@ -224,6 +225,12 @@ readnumber(struct source *src, u_int bas
  if (v > 0)
  #endif
  bn_check(BN_add_word(n->number, v));
 + }
 + if (base != 10) {
 + for (i = 0; i < n->scale; i++)
 + BN_mul_word(n->number, 10);
 + for (i = 0; i < n->scale; i++)
 + BN_div_word(n->number, base);
  }
  if (sign)
  negate(n);