Rémy Oudompheng | 2ece2f5 | 2012-02-18 22:15:42 +0100 | [diff] [blame] | 1 | // run |
Russ Cox | f333f46 | 2008-11-17 12:33:49 -0800 | [diff] [blame] | 2 | |
| 3 | // Copyright 2009 The Go Authors. All rights reserved. |
| 4 | // Use of this source code is governed by a BSD-style |
| 5 | // license that can be found in the LICENSE file. |
| 6 | |
| 7 | package main |
| 8 | |
Russ Cox | 918afd94 | 2009-05-08 15:21:41 -0700 | [diff] [blame] | 9 | import "os" |
Rob Pike | 325cf8e | 2010-03-24 16:46:53 -0700 | [diff] [blame] | 10 | import "strconv" |
Russ Cox | f333f46 | 2008-11-17 12:33:49 -0800 | [diff] [blame] | 11 | |
Russ Cox | 839a684 | 2009-01-20 14:40:40 -0800 | [diff] [blame] | 12 | type Test struct { |
Rob Pike | 325cf8e | 2010-03-24 16:46:53 -0700 | [diff] [blame] | 13 | f float64 |
| 14 | in string |
| 15 | out string |
Russ Cox | f333f46 | 2008-11-17 12:33:49 -0800 | [diff] [blame] | 16 | } |
| 17 | |
Rob Pike | 325cf8e | 2010-03-24 16:46:53 -0700 | [diff] [blame] | 18 | var tests = []Test{ |
| 19 | Test{123.5, "123.5", "123.5"}, |
| 20 | Test{456.7, "456.7", "456.7"}, |
| 21 | Test{1e23 + 8.5e6, "1e23+8.5e6", "1.0000000000000001e+23"}, |
| 22 | Test{100000000000000008388608, "100000000000000008388608", "1.0000000000000001e+23"}, |
| 23 | Test{1e23 + 8388609, "1e23+8388609", "1.0000000000000001e+23"}, |
Russ Cox | a1585b6 | 2008-11-17 13:58:45 -0800 | [diff] [blame] | 24 | |
| 25 | // "x" = the floating point value from converting the string x. |
| 26 | // These are exactly representable in 64-bit floating point: |
| 27 | // 1e23-8388608 |
| 28 | // 1e23+8388608 |
| 29 | // The former has an even mantissa, so "1e23" rounds to 1e23-8388608. |
| 30 | // If "1e23+8388608" is implemented as "1e23" + "8388608", |
| 31 | // that ends up computing 1e23-8388608 + 8388608 = 1e23, |
| 32 | // which rounds back to 1e23-8388608. |
| 33 | // The correct answer, of course, would be "1e23+8388608" = 1e23+8388608. |
| 34 | // This is not going to be correct until 6g has multiprecision floating point. |
| 35 | // A simpler case is "1e23+1", which should also round to 1e23+8388608. |
Rob Pike | 325cf8e | 2010-03-24 16:46:53 -0700 | [diff] [blame] | 36 | Test{1e23 + 8.388608e6, "1e23+8.388608e6", "1.0000000000000001e+23"}, |
| 37 | Test{1e23 + 1, "1e23+1", "1.0000000000000001e+23"}, |
Russ Cox | be2edb5 | 2009-03-03 08:39:12 -0800 | [diff] [blame] | 38 | } |
Russ Cox | f333f46 | 2008-11-17 12:33:49 -0800 | [diff] [blame] | 39 | |
| 40 | func main() { |
Rob Pike | 325cf8e | 2010-03-24 16:46:53 -0700 | [diff] [blame] | 41 | ok := true |
Russ Cox | f333f46 | 2008-11-17 12:33:49 -0800 | [diff] [blame] | 42 | for i := 0; i < len(tests); i++ { |
Rob Pike | 325cf8e | 2010-03-24 16:46:53 -0700 | [diff] [blame] | 43 | t := tests[i] |
Russ Cox | 2666b81 | 2011-12-05 15:48:46 -0500 | [diff] [blame] | 44 | v := strconv.FormatFloat(t.f, 'g', -1, 64) |
Russ Cox | f333f46 | 2008-11-17 12:33:49 -0800 | [diff] [blame] | 45 | if v != t.out { |
Rob Pike | 325cf8e | 2010-03-24 16:46:53 -0700 | [diff] [blame] | 46 | println("Bad float64 const:", t.in, "want", t.out, "got", v) |
Russ Cox | 2666b81 | 2011-12-05 15:48:46 -0500 | [diff] [blame] | 47 | x, err := strconv.ParseFloat(t.out, 64) |
Russ Cox | 6cc001c | 2008-11-18 17:12:07 -0800 | [diff] [blame] | 48 | if err != nil { |
Rob Pike | 325cf8e | 2010-03-24 16:46:53 -0700 | [diff] [blame] | 49 | println("bug120: strconv.Atof64", t.out) |
| 50 | panic("fail") |
Russ Cox | a1585b6 | 2008-11-17 13:58:45 -0800 | [diff] [blame] | 51 | } |
Russ Cox | 2666b81 | 2011-12-05 15:48:46 -0500 | [diff] [blame] | 52 | println("\twant exact:", strconv.FormatFloat(x, 'g', 1000, 64)) |
| 53 | println("\tgot exact: ", strconv.FormatFloat(t.f, 'g', 1000, 64)) |
Rob Pike | 325cf8e | 2010-03-24 16:46:53 -0700 | [diff] [blame] | 54 | ok = false |
Russ Cox | f333f46 | 2008-11-17 12:33:49 -0800 | [diff] [blame] | 55 | } |
| 56 | } |
| 57 | if !ok { |
Rob Pike | 325cf8e | 2010-03-24 16:46:53 -0700 | [diff] [blame] | 58 | os.Exit(1) |
Russ Cox | f333f46 | 2008-11-17 12:33:49 -0800 | [diff] [blame] | 59 | } |
| 60 | } |