Hi Alexander,

Thanks, this is interesting.  My original

func Round(x float64, digits int) float64 {
eps := math.Pow10(-digits)
return math.Round(x/eps) * eps
}

leads to near-immediate fuzzing failures, whereas your

func Round(x float64, digits int) float64 {
   scale := math.Pow(10, float64(digits)) 
  return math.Round(x*scale) / scale 
}

has now survived 4 minutes of fuzzing.  Maybe the difference is that scale 
can be represented exactly, while eps has truncation error?

Many thanks,
Jochen
On Wednesday, 13 August 2025 at 14:07:46 UTC+1 Alexander Ertli wrote:

> Hi Jochen,
>
> I think it's possible with a trick.
>
> My first naive thought on how to solve this is to simply shift the decimal 
> point over, do the rounding on the whole number, and then shift it back.
> import "math" 
> // Round performs rounding by shifting the decimal, rounding, and shifting 
> back. 
> func Round(x float64, digits int) float64 {
>    scale := math.Pow(10, float64(digits)) 
>   return math.Round(x*scale) / scale 
> }
>
> https://go.dev/play/p/_DVsD45FAKb
>
>
> Am Mi., 13. Aug. 2025 um 14:51 Uhr schrieb robert engels <
> ren...@ix.netcom.com>:
>
>> Read up on numerical analysis - what you are asking for is impossible :)
>>
>> You need to convert to a string, or use BCD/fixed place values - like 
>> github.com/robaho/fixed
>>
>> On Aug 13, 2025, at 7:42 AM, Jochen Voss <joche...@gmail.com> wrote:
>>
>> Dear all,
>>
>> I would like to define a function "func Round(x float64, digits int) 
>> float64" which rounds to the given number of digits, in the sense that I 
>> want "strconv.FormatFloat(x, 'f', -1, 64)" to show at most the given 
>> number of digits after the decimal point.
>>
>> The following naive approach does not work:
>>
>> func Round(x float64, digits int) float64 {
>> eps := math.Pow10(-digits)
>> return math.Round(x/eps) * eps
>> }
>>
>> For example for rounding math.Pi to five digits I get "3.1415900000000003" 
>> instead of "3.14159".  https://go.dev/play/p/gRtHG6ZgTjj .
>>
>> Anthropic's Claude suggested the following:
>>
>> func Round(x float64, digits int) float64 {
>> if digits <= 0 {
>> pow := math.Pow10(-digits)
>> return math.Round(x/pow) * pow
>> }
>>
>> format := "%." + strconv.Itoa(digits) + "f"
>> s := fmt.Sprintf(format, x)
>> result, _ := strconv.ParseFloat(s, 64)
>>
>> return result
>> }
>>
>> This seems to work, but also seems quite inefficient.
>>
>> Is there a better way?
>>
>> All the best,
>> Jochen
>>
>> PS.: Here is some testing code for experimenting 
>> https://go.dev/play/p/Xcd6fTvYend
>>
>>
>>
>> -- 
>> 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...@googlegroups.com.
>> To view this discussion visit 
>> https://groups.google.com/d/msgid/golang-nuts/7d3ccdd4-d88b-4eba-8a36-02b51b7751e1n%40googlegroups.com
>>  
>> <https://groups.google.com/d/msgid/golang-nuts/7d3ccdd4-d88b-4eba-8a36-02b51b7751e1n%40googlegroups.com?utm_medium=email&utm_source=footer>
>> .
>>
>>
>> -- 
>> 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...@googlegroups.com.
>>
> To view this discussion visit 
>> https://groups.google.com/d/msgid/golang-nuts/234384D7-17A3-45B3-959C-8CE0D3F44BF5%40ix.netcom.com
>>  
>> <https://groups.google.com/d/msgid/golang-nuts/234384D7-17A3-45B3-959C-8CE0D3F44BF5%40ix.netcom.com?utm_medium=email&utm_source=footer>
>> .
>>
>

-- 
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.
To view this discussion visit 
https://groups.google.com/d/msgid/golang-nuts/27ae793c-3018-46c4-b2d3-4f2854ffdbb2n%40googlegroups.com.

Reply via email to