I'm getting an unexpected result of big.Rat.Quo().  In trying to track it 
down, I ran into an unexpected result from big.Rat.SetFloat64().  So I have 
a few questions...

Code snippet below reproduces what I see in my application, and is also in 
https://play.golang.org/p/Eph67_1yd-

I'm working with data that includes pairs of decimal numbers, and I need 
the ratio between each pair.  Originally, I started implementing with 
float64s.  But I ran into some rounding errors and something I read 
somewhere (maybe this list) led me to think that big.Rat would be a better 
choice.  Using bigRat solved my problem at the time, but now in processing 
a particular list of numbers I'm noticing an error.

The result I would like is for input two values, 118.5285714285714 
and 8297.0, is an output ratio should be 0.01428571428571428.  I get this 
on a calculator, but not code using bit.Rat.

Using big.Rat, getting the 8297 denominator is straightforward.

Getting the numerator is tricky.  Note these two approaches get different 
results:

    numerator.SetFloat64(118.5285714285714) // becomes 
118.528571428571396495499357115477
    big.NewRat(592642857142857, 5000000000000) // becomes 
118.528571428571400000000000000000 - more accurate than SetFloat64 above!


So my first question is why is SetFloat64() less accurate than the ratio 
used in NewRat() above?

Next question is why do neither of these numerators get the expected result 
from big.Rat.Quo()?  See output of code below (shown in comments).

And given these problems, should I be using some other package to perform 
this math?  Or, am I making some mistake in how I use big.Rat?

Whole code snippet:

package main

import (
"fmt"
"math/big"
)

func main() {

var numerator, denominator, result big.Rat

// These are two ways to get not quite the same big.Rat value:

numerator.SetFloat64(118.5285714285714) // becomes 
118.528571428571396495499357115477

numerator2 := big.NewRat(592642857142857, 5000000000000) // becomes 
118.528571428571400000000000000000 - more accurate than SetFloat64 above!

denominator.SetInt64(8297) // remains 8297.0000000...

for _, num := range []*big.Rat{&numerator, numerator2} {

result.Quo(num, &denominator) // Expected result: 0.01428571428571428

// Show results as fractions.
fmt.Printf("%s over %s is %s\n", num.String(), denominator.String(), 
result.String())

// Show a lot of decimal places.
fmt.Printf("%s over %s is %s\n\n", num.FloatString(30), 
denominator.FloatString(30), result.FloatString(30))

}

// Output:

// 8340706720601115/70368744177664 over 8297/1 is 
8340706720601115/583849470442078208
// 118.528571428571396495499357115477 over 
8297.000000000000000000000000000000 is 0.014285714285714281848318591915

// 592642857142857/5000000000000 over 8297/1 is 
592642857142857/41485000000000000
// 118.528571428571400000000000000000 over 
8297.000000000000000000000000000000 is 0.014285714285714282270700253104

}





-- 
You received this message because you are subscribed to the Google Groups 
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to golang-nuts+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to