keep just 2 decimal places in a float64

4,356 views
Skip to first unread message

Jason E. Aten

unread,
Jan 25, 2020, 10:14:15 PM1/25/20
to golang-nuts


I'd like to truncate a float64 to just 2 decimal places (in base 10), but math.Trunc is not helping me here... ideally I put 0.29 in and I get 0.29 out.
Suggestions?  Playground examples appreciated.

package main

import (
"fmt"
"math"
)

// truncate off everything after the last two decimals, no rounding.
func decimal2(x float64) float64 {
    return math.Trunc(x*100) / 100
}

func main() {
        x := 0.29
        y := decimal2(x)
fmt.Printf("x=%v -> y = %v", x, y) // prints x=0.29  ->  y=0.28
}

Kurtis Rader

unread,
Jan 25, 2020, 10:34:11 PM1/25/20
to Jason E. Aten, golang-nuts
You've fallen into a common trap. Base 2 floating point values cannot represent most decimal values precisely. This is why you should never, ever, do a simple equality test involving a F.P. value derived from a calculation. You always have to apply an epsilon to define a range within which the two F.P. values should be considered equal. The %v formatter does something similar. The base 10 value 0.29 is actually 0.28999999999999998002 when stored base 2 (that's from printing a long double var on a x86_64 platform).

Welcome to floating point pitfalls. Here be dragons!


--
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 on the web visit https://groups.google.com/d/msgid/golang-nuts/96528d64-a670-45ba-ad4c-0701dcd0d78d%40googlegroups.com.


--
Kurtis Rader
Caretaker of the exceptional canines Junior and Hank

Aston Motes

unread,
Jan 26, 2020, 12:10:11 AM1/26/20
to Kurtis Rader, Jason E. Aten, golang-nuts

crate...@gmail.com

unread,
Jan 26, 2020, 12:26:38 AM1/26/20
to golang-nuts
Floating point math has many pitfalls.  https://play.golang.org/p/LK0lla8hM9w See also https://0.30000000000000004.com/

s

Kurtis Rader

unread,
Jan 26, 2020, 12:40:08 AM1/26/20
to crate...@gmail.com, golang-nuts
On Sat, Jan 25, 2020 at 9:26 PM <crate...@gmail.com> wrote:
Floating point math has many pitfalls.  https://play.golang.org/p/LK0lla8hM9w See also https://0.30000000000000004.com/

I was not aware of URL https://0.30000000000000004.com/. Like the XY problem URL, http://xyproblem.info/, the URL you cited is another one to remember to cite when a FAQ about floating point values occurs :-)

Jamil Djadala

unread,
Jan 26, 2020, 12:40:41 AM1/26/20
to golan...@googlegroups.com
On Sat, 25 Jan 2020 19:14:15 -0800 (PST)
"Jason E. Aten" <j.e....@gmail.com> wrote:

>
> https://play.golang.org/p/87bDubJxjHO
>
> I'd like to truncate a float64 to just 2 decimal places (in base 10),
> but math.Trunc is not helping me here... ideally I put 0.29 in and I
> get 0.29 out.
> Suggestions? Playground examples appreciated.

you can use int types:
https://play.golang.org/p/qLnynemd3S1
--
Jamil Djadala

Robert Engels

unread,
Jan 26, 2020, 12:47:05 AM1/26/20
to Jamil Djadala, golan...@googlegroups.com
You can use github.com/robaho/fixed :)

> On Jan 25, 2020, at 11:40 PM, Jamil Djadala <dja...@datamax.bg> wrote:
>
> On Sat, 25 Jan 2020 19:14:15 -0800 (PST)
> --
> 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 on the web visit https://groups.google.com/d/msgid/golang-nuts/20200126074011.0f17b4fa%40wolf.home.

Pat Farrell

unread,
Jan 26, 2020, 9:50:11 AM1/26/20
to golang-nuts
never use floating point if you are trying to represent money, say dollars and cents or decimal values of the euro.
Store the money as integer number of pennies.

Robert Engels

unread,
Jan 26, 2020, 11:20:27 AM1/26/20
to Pat Farrell, golang-nuts
Just an FYI, often that is not correct. Many financial systems require fractional pennies due to the volume of transactions. Think about taxing stock exchanges.... the pennies add up quickly at any tax rate, so they use fractional pennies to reduce the size of the error bucket. 

On Jan 26, 2020, at 8:50 AM, Pat Farrell <pat2...@gmail.com> wrote:


never use floating point if you are trying to represent money, say dollars and cents or decimal values of the euro.
Store the money as integer number of pennies.

--
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.

Peter Weinberger (温博格)

unread,
Jan 26, 2020, 11:33:38 AM1/26/20
to Robert Engels, Pat Farrell, golang-nuts
And from Wikipedia on the Vancouver Stock Exchange.
"The history of the exchange's index provides a standard case example of large errors arising from seemingly innocuous floating point calculations. In January 1982 the index was initialized at 1000 and subsequently updated and truncated to three decimal places on each trade. Such a thing was done about 3000 times each day. The accumulated truncations led to an erroneous loss of around 25 points per month. Over the weekend of November 25–28, 1983, the error was corrected, raising the value of the index from its Friday closing figure of 524.811 to 1098.892"

Michael Jones

unread,
Jan 26, 2020, 11:34:52 AM1/26/20
to Robert Engels, Pat Farrell, golang-nuts
...thus the virtue of scaled integers. scaling by 100 makes cents whole, scaling by 10000*100 gives four decimal places beyond that. There is nothing bad about floating point despite the reputation, it's just not the number system from algebra; nor is binary floating point the same as decimal floating point. The problems all start with false presumptions.



--
Michael T. Jones
michae...@gmail.com

Robert Engels

unread,
Jan 26, 2020, 11:46:16 AM1/26/20
to Michael Jones, Pat Farrell, golang-nuts
Which is exactly what github.com/robaho/fixed and many others do!

On Jan 26, 2020, at 10:34 AM, Michael Jones <michae...@gmail.com> wrote:



crate...@gmail.com

unread,
Feb 1, 2020, 5:03:11 PM2/1/20
to golang-nuts
Perhaps I'm doing something wrong or using the library outside of its intended purpose, but I found that this library doesn't handle Muller's Recurrence correctly. For those not familiar, Muller's Recurrence is 108 - (815-1500/z)/y


On Sunday, January 26, 2020 at 8:46:16 AM UTC-8, Robert Engels wrote:
Which is exactly what github.com/robaho/fixed and many others do!

On Jan 26, 2020, at 10:34 AM, Michael Jones <michae...@gmail.com> wrote:


...thus the virtue of scaled integers. scaling by 100 makes cents whole, scaling by 10000*100 gives four decimal places beyond that. There is nothing bad about floating point despite the reputation, it's just not the number system from algebra; nor is binary floating point the same as decimal floating point. The problems all start with false presumptions.

On Sun, Jan 26, 2020 at 8:20 AM Robert Engels <ren...@ix.netcom.com> wrote:
Just an FYI, often that is not correct. Many financial systems require fractional pennies due to the volume of transactions. Think about taxing stock exchanges.... the pennies add up quickly at any tax rate, so they use fractional pennies to reduce the size of the error bucket. 

On Jan 26, 2020, at 8:50 AM, Pat Farrell <pat2...@gmail.com> wrote:


never use floating point if you are trying to represent money, say dollars and cents or decimal values of the euro.
Store the money as integer number of pennies.

--
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 golan...@googlegroups.com.

--
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 golan...@googlegroups.com.

Robert Engels

unread,
Feb 1, 2020, 6:11:08 PM2/1/20
to crate...@gmail.com, golang-nuts
fixed only supports 8 decimals places - fixed. Without digging into the algorithm I’m sure that is the source of your issue. 


On Feb 1, 2020, at 4:03 PM, crate...@gmail.com wrote:


To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/46cadc14-9c8e-4c3a-9c6b-d0af7b621061%40googlegroups.com.

Manlio Perillo

unread,
Feb 1, 2020, 6:48:23 PM2/1/20
to golang-nuts
Even if fixed supports 7 decimal places, those 7 decimal places should have the same value (after rounding) as the result provided by math.Big.
I suspect the precision loss is in the Div method: https://github.com/robaho/fixed/blob/master/fixed.go#L232


Manlio Perillo

Michael Jones

unread,
Feb 1, 2020, 7:36:20 PM2/1/20
to crate...@gmail.com, golang-nuts
Your expectations are wrong in the sense of being overly optimistic. 

This is a chaotic attractor, under any form of rounding or precision it will “fail” in the way you mean (and “succeed” in proving the power of a strong attractor!)

I have this as a test at home that does each step in 32, 64, doubled precision (~120 bit fp at 1/4 of full speed), and big. I’ll send it later today. 

No matter what you choose to do, the chaotic attractor will win.

Michael

To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/46cadc14-9c8e-4c3a-9c6b-d0af7b621061%40googlegroups.com.

Jason E. Aten

unread,
Feb 1, 2020, 8:54:21 PM2/1/20
to golang-nuts
I appreciate the sophisticated and math conscious discussion here.

For those reading this thread in the future, I note the state of the art in Go at the moment seems to be this
arbitrary precision decimal library created by the CockroachDB guys for APD standard/postgresql conformance.
Note that arbitrary doesn't mean infinite, it means you can pick the precision your application needs.

Michael Jones

unread,
Feb 1, 2020, 10:33:04 PM2/1/20
to Jason E. Aten, golang-nuts
As promised, some careful results from one of the tests in my doubled-precision library. 

Rows are iteration's of Jean-Michel Muller's roundoff-intolerant Œ() function:

Columns are 32-bit floating point,64-bit floating point, my fast 128-bit library, Go big float, and Go rationals (printed as float)

Answers are good for a while, and then fail as they must. compare always to the right column.

Also, Dr. Kahan on the topic -- always read his every word!
How Futile are Mindless Assessments of Roundoff In Floating-Point Computation ?
Professor W. Kahan
§ 5, page 14

=== RUN   TestMuller
  0:   4.000000000   4.000000000000000000 +4.0000000000000000000000000000000e+00 4.0000000000000000000000000000000 4.0000000000000000000000000000000000000000000000000000000000000000000000…
  1:   4.250000000   4.250000000000000000 +4.2500000000000000000000000000000e+00 4.2500000000000000000000000000000 4.2500000000000000000000000000000000000000000000000000000000000000000000…
  2:   4.470588684   4.470588235294115975 +4.4705882352941176470588235294117e+00 4.4705882352941176470588235294118 4.4705882352941176470588235294117647058823529411764705882352941176470588…
  3:   4.644744873   4.644736842105217534 +4.6447368421052631578947368421047e+00 4.6447368421052631578947368421053 4.6447368421052631578947368421052631578947368421052631578947368421052632…
  4:   4.770706177   4.770538243625082941 +4.7705382436260623229461756373816e+00 4.7705382436260623229461756373938 4.7705382436260623229461756373937677053824362606232294617563739376770538…
  5:   4.859214783   4.855700712568562949 +4.8557007125890736342042755341875e+00 4.8557007125890736342042755344418 4.8557007125890736342042755344418052256532066508313539192399049881235154…
  6:   4.983123779   4.910847498660629640 +4.9108474990827932004402592585550e+00 4.9108474990827932004402592637887 4.9108474990827932004402592637886755533814357343769108474990827932004403…
  7:   6.395431519   4.945537395530507752 +4.9455374041239167247733836966321e+00 4.9455374041239167247733838031676 4.9455374041239167247733838031676461798983962546070325729654348042633728…
  8:  27.632629395   4.966962408040998866 +4.9669625817627005987119363335665e+00 4.9669625817627005987119384872579 4.9669625817627005987119384872578590383346845054961655244646085209448470…
  9:  86.993759155   4.980042204293013697 +4.9800457013556311612685646399287e+00 4.9800457013556311612686079942904 4.9800457013556311612686079942903718963021236734644222853921922457735370…
 10:  99.255508423   4.987909232795786352 +4.9879794484783922601392624051427e+00 4.9879794484783922601401328939769 4.9879794484783922601401328939769400999972111033913186330660946103656976…
 11:  99.962585449   4.991362641314552206 +4.9927702880620680974721416957309e+00 4.9927702880620680974895925483283 4.9927702880620680974895925483282696604561239860070565468956074766812844…
 12:  99.998130798   4.967455095552267608 +4.9956558915066340262745164361610e+00 4.9956558915066340266240282615671 4.9956558915066340266240282615670560447223264138375322338595040105640829…
 13:  99.999908447   4.429690498308829660 +4.9973912683813441058976817599037e+00 4.9973912683813441128938690216426 4.9973912683813441128938690216425944791795065582105346913888017869771418…
 14: 100.000000000  -7.817236578459315410 +4.9984339439448167790186456309858e+00 4.9984339439448169190138971781902 4.9984339439448169190138971781902382881448247682045125641413593279228615…
 15: 100.000000000 168.939167671064581100 +4.9990600719708910670530314075958e+00 4.9990600719708938678168396062869 4.9990600719708938678168396062869249162956010827138675312945769521384463…
 16: 100.000000000 102.039963152059272034 +4.9994359371467831224113039612204e+00 4.9994359371468391479978508864998 4.9994359371468391479978508864997899689960802031068986343509970885820809…
 17: 100.000000000 100.099947516249699220 +4.9996615241026469022949297281691e+00 4.9996615241037675377868879857271 4.9996615241037675377868879857270921122953326315959962489248369318086283…
 18: 100.000000000 100.004992040972439327 +4.9997969006910037174292363662054e+00 4.9997969007134179126629930746330 4.9997969007134179126629930746330014204806141590496819671038715851326606…
 19: 100.000000000 100.000249579237305397 +4.9998781350296295179302235821482e+00 4.9998781354779312492317320300204 4.9998781354779312492317320300204045157850179321411177471298083841044938…
 20: 100.000000000 100.000012478620163847 +4.9999268705383513445350585201744e+00 4.9999268795045999044664529810255 4.9999268795045999044664529810255297667014507019629318651153480676099193…
 21: 100.000000000 100.000000623921607712 +4.9999559477336189227766623157740e+00 4.9999561270611577381190152822945 4.9999561270611577381190152822944886054388799381889725655444194135741792…
 22: 100.000000000 100.000000031195796169 +4.9999700894239992550386653856177e+00 4.9999736760057124445790151493568 4.9999736760057124445790151493567643737503007922741653125691208832859521…
 23: 100.000000000 100.000000001559783414 +4.9999124734648500146469791816450e+00 4.9999842055202727079241797881427 4.9999842055202727079241797881426658531818881745189289851152851242815919…
 24: 100.000000000 100.000000000077989171 +4.9985558571549103233951637188660e+00 4.9999905232822276594072074700222 4.9999905232822276594072074700221895687712348995633004631696331458335230…
 25: 100.000000000 100.000000000003893774 +4.9712927027118246836857185407072e+00 4.9999943139585595936498116895205 4.9999943139585595936498116895205444125570648227907768610955390115520007…
 26: 100.000000000 100.000000000000198952 +4.4226495626383376905144334349236e+00 4.9999965883712560237063808793366 4.9999965883712560237063808793366290715938072692305936798744398732101066…
 27: 100.000000000 100.000000000000014211 -8.0543263668793762606068650955197e+00 4.9999979530213569079884128681396 4.9999979530213569079884128681395624212191657293654124963639370253143521…
 28: 100.000000000 100.000000000000000000 +1.6707840996047266994803982209542e+02 4.9999987718123113299993645145089 4.9999987718123113299993645145089043394808989018478270361242267297207022…
 29: 100.000000000 100.000000000000000000 +1.0200739261142367556227366287163e+02 4.9999992630872057845553229449429 4.9999992630872057845553229449428974248701745617859182826712196402811665…
 30: 100.000000000 100.000000000000000000 +1.0009839445249753858622122905694e+02 4.9999995578522583058676361926155 4.9999995578522583058676361926155306470579794114384348546804011194603975…
 31: 100.000000000 100.000000000000000000 +1.0000491488620529657993721950960e+02 4.9999997347113315241634489886704 4.9999997347113315241634489886703873209071815584704240641160206715019947…
 32: 100.000000000 100.000000000000000000 +1.0000024573221949273744163542145e+02 4.9999998408267904691283066991447 4.9999998408267904691283066991447461401245221411111941292349839150736202…
 33: 100.000000000 100.000000000000000000 +1.0000001228658038317581341424617e+02 4.9999999044960712411436113485087 4.9999999044960712411436113485086619025952254222132465962859727857685148…
 34: 100.000000000 100.000000000000000000 +1.0000000061432893169757060234937e+02 4.9999999426976416501660968977059 4.9999999426976416501660968977058746597449338657490050051607246193821182…
 35: 100.000000000 100.000000000000000000 +1.0000000003071644603674249773981e+02 4.9999999656185845960724209285520 4.9999999656185845960724209285520274032984329752720101455505569667883150…
 36: 100.000000000 100.000000000000000000 +1.0000000000153582229058229440059e+02 4.9999999793711506157936445604403 4.9999999793711506157936445604403478825768055203979330788072542784010734…
 37: 100.000000000 100.000000000000000000 +1.0000000000007679111420444293124e+02 4.9999999876226903184102552956254 4.9999999876226903184102552956254154564530233074230759247801804451248680…
 38: 100.000000000 100.000000000000000000 +1.0000000000000383955570051442571e+02 4.9999999925736141726624177373900 4.9999999925736141726624177373899846521814871450561974997770093507650710…
 39: 100.000000000 100.000000000000000000 +1.0000000000000019197778473457074e+02 4.9999999955441684969793058578266 4.9999999955441684969793058578265507221613846754127192411902416952952377…
 40: 100.000000000 100.000000000000000000 +1.0000000000000000959888922799422e+02 4.9999999973265010958050513865753 4.9999999973265010958050513865752991029792463868833735614796518031109060…
 41: 100.000000000 100.000000000000000000 +1.0000000000000000047994446113768e+02 4.9999999983959006566253192645988 4.9999999983959006566253192645987703517412541034104279060966324365686654…
 42: 100.000000000 100.000000000000000000 +1.0000000000000000002399722304902e+02 4.9999999990375403936664153942504 4.9999999990375403936664153942503908554421709588719708303898585404793654…
 43: 100.000000000 100.000000000000000000 +1.0000000000000000000119986115222e+02 4.9999999994225242360886898172700 4.9999999994225242360886898172699813847756164760214959144068009828924029…
 44: 100.000000000 100.000000000000000000 +1.0000000000000000000005999305760e+02 4.9999999996535145416131964994088 4.9999999996535145416131964994087728654592174856780594689249370593190948…
 45: 100.000000000 100.000000000000000000 +1.0000000000000000000000299965288e+02 4.9999999997921087249535116388994 4.9999999997921087249535116388994438064719403073280296047563240880153629…
 46: 100.000000000 100.000000000000000000 +1.0000000000000000000000014998264e+02 4.9999999998752652349669207294706 4.9999999998752652349669207294705960875781484796796781602905760999707614…
 47: 100.000000000 100.000000000000000000 +1.0000000000000000000000000749913e+02 4.9999999999251591409782853862894 4.9999999999251591409782853862893681758947903446625524375301891071583939…
 48: 100.000000000 100.000000000000000000 +1.0000000000000000000000000037496e+02 4.9999999999550954845862990932721 4.9999999999550954845862990932721178654499411656001666991067834528381427…
 49: 100.000000000 100.000000000000000000 +1.0000000000000000000000000001875e+02 4.9999999999730572907515374861027 4.9999999999730572907515374861027238298843581825471452918011046606547147…
 50: 100.000000000 100.000000000000000000 +1.0000000000000000000000000000094e+02 4.9999999999838343744508353825118 4.9999999999838343744508353825118361660416654324053402436169810652257114…
 51: 100.000000000 100.000000000000000000 +1.0000000000000000000000000000005e+02 4.9999999999903006246704698702132 4.9999999999903006246704698702131741017755891186085659779488544485080641…
 52: 100.000000000 100.000000000000000000 +1.0000000000000000000000000000000e+02 4.9999999999941803748022706327821 4.9999999999941803748022706327820904674397779407686765412987426353340860…
 53: 100.000000000 100.000000000000000000 +1.0000000000000000000000000000000e+02 4.9999999999965082248813583155048 4.9999999999965082248813583155047612301443053914242084554581965117999475…
 54: 100.000000000 100.000000000000000000 +1.0000000000000000000000000000000e+02 4.9999999999979049349288135262036 4.9999999999979049349288135262036392372468406372184837633675327240105601…
 55: 100.000000000 100.000000000000000000 +1.0000000000000000000000000000000e+02 4.9999999999987429609572875890065 4.9999999999987429609572875890064652414572617384587447652026097603020003…
 56: 100.000000000 100.000000000000000000 +1.0000000000000000000000000000000e+02 4.9999999999992457765743723637862 4.9999999999992457765743723637862205564265300645967804237671219621887640…
 57: 100.000000000 100.000000000000000000 +1.0000000000000000000000000000000e+02 4.9999999999995474659446233500094 4.9999999999995474659446233500093752419872416231419626221316696321618204…
 58: 100.000000000 100.000000000000000000 +1.0000000000000000000000000000000e+02 4.9999999999997284795667739854312 4.9999999999997284795667739854311765921136903843367833565912666882127043…
 59: 100.000000000 100.000000000000000000 +1.0000000000000000000000000000000e+02 4.9999999999998370877400643824119 4.9999999999998370877400643824119044761586174651005029403286560095136689…
 60: 100.000000000 100.000000000000000000 +1.0000000000000000000000000000000e+02 4.9999999999999022526440386262623 4.9999999999999022526440386262622941532154389230146822149898257515887795…
 61: 100.000000000 100.000000000000000000 +1.0000000000000000000000000000000e+02 4.9999999999999413515864231746108 4.9999999999999413515864231746108310202365002220119343179337646326275894…
 62: 100.000000000 100.000000000000000000 +1.0000000000000000000000000000000e+02 4.9999999999999648109518539043537 4.9999999999999648109518539043537422423324924950902679597114922320542682…
 63: 100.000000000 100.000000000000000000 +1.0000000000000000000000000000000e+02 4.9999999999999788865711123424637 4.9999999999999788865711123424636530522681059586273556210959868830755301…
 64: 100.000000000 100.000000000000000000 +1.0000000000000000000000000000000e+02 4.9999999999999873319426674054247 4.9999999999999873319426674054246986058335627389825431745090925770748517…
 65: 100.000000000 100.000000000000000000 +1.0000000000000000000000000000000e+02 4.9999999999999923991656004432356 4.9999999999999923991656004432355616023103092122499250394020004968086813…
 66: 100.000000000 100.000000000000000000 +1.0000000000000000000000000000000e+02 4.9999999999999954394993602659344 4.9999999999999954394993602659344042393578472640359802718342049154159509…
 67: 100.000000000 100.000000000000000000 +1.0000000000000000000000000000000e+02 4.9999999999999972636996161595581 4.9999999999999972636996161595581467636845065775581540693456601285917415…
 68: 100.000000000 100.000000000000000000 +1.0000000000000000000000000000000e+02 4.9999999999999983582197696957340 4.9999999999999983582197696957339895774358313041128490803051031466354659…
 69: 100.000000000 100.000000000000000000 +1.0000000000000000000000000000000e+02 4.9999999999999990149318618174401 4.9999999999999990149318618174400702933825446309125531072033187866180516…
 70: 100.000000000 100.000000000000000000 +1.0000000000000000000000000000000e+02 4.9999999999999994089591170904639 4.9999999999999994089591170904639257329211032839264999036925254782439621…
 71: 100.000000000 100.000000000000000000 +1.0000000000000000000000000000000e+02 4.9999999999999996453754702542783 4.9999999999999996453754702542783135202336295122791144899675278048175021…
 72: 100.000000000 100.000000000000000000 +1.0000000000000000000000000000000e+02 4.9999999999999997872252821525670 4.9999999999999997872252821525669730211133260224569717187442231522023258…
 73: 100.000000000 100.000000000000000000 +1.0000000000000000000000000000000e+02 4.9999999999999998723351692915402 4.9999999999999998723351692915401783798983290069057876102772323241125098…
 74: 100.000000000 100.000000000000000000 +1.0000000000000000000000000000000e+02 4.9999999999999999234011015749241 4.9999999999999999234011015749241050721419174257787170484823958766829884…
 75: 100.000000000 100.000000000000000000 +1.0000000000000000000000000000000e+02 4.9999999999999999540406609449545 4.9999999999999999540406609449544623391982016632558894788380589496296748…
 76: 100.000000000 100.000000000000000000 +1.0000000000000000000000000000000e+02 4.9999999999999999724243965669727 4.9999999999999999724243965669726771500476194327574448042131447577254700…
 77: 100.000000000 100.000000000000000000 +1.0000000000000000000000000000000e+02 4.9999999999999999834546379401836 4.9999999999999999834546379401836061987789030961838735426077722601924147…
 78: 100.000000000 100.000000000000000000 +1.0000000000000000000000000000000e+02 4.9999999999999999900727827641102 4.9999999999999999900727827641101636864174611748609102333197316917095417…
 79: 100.000000000 100.000000000000000000 +1.0000000000000000000000000000000e+02 4.9999999999999999940436696584661 4.9999999999999999940436696584660982000245196590907570761709464871917991…
 80: 100.000000000 100.000000000000000000 +1.0000000000000000000000000000000e+02 4.9999999999999999964262017950797 4.9999999999999999964262017950796589157573672589571701692026996825069414…
 81: 100.000000000 100.000000000000000000 +1.0000000000000000000000000000000e+02 4.9999999999999999978557210770478 4.9999999999999999978557210770477953479217763222352798310604083236190434…
 82: 100.000000000 100.000000000000000000 +1.0000000000000000000000000000000e+02 4.9999999999999999987134326462287 4.9999999999999999987134326462286772082013139414111198806392169302962769…
 83: 100.000000000 100.000000000000000000 +1.0000000000000000000000000000000e+02 4.9999999999999999992280595877372 4.9999999999999999992280595877372063247221576981518546417683057985281073…
 84: 100.000000000 100.000000000000000000 +1.0000000000000000000000000000000e+02 4.9999999999999999995368357526423 4.9999999999999999995368357526423237947617875788809785618500631502055925…
 85: 100.000000000 100.000000000000000000 +1.0000000000000000000000000000000e+02 4.9999999999999999997221014515854 4.9999999999999999997221014515853942768313300129249388167477476268768203…
 86: 100.000000000 100.000000000000000000 +1.0000000000000000000000000000000e+02 4.9999999999999999998332608709512 4.9999999999999999998332608709512365660895306953696498947168505492722285…
 87: 100.000000000 100.000000000000000000 +1.0000000000000000000000000000000e+02 4.9999999999999999998999565225707 4.9999999999999999998999565225707419396503821847630771145103663569655621…
 88: 100.000000000 100.000000000000000000 +1.0000000000000000000000000000000e+02 4.9999999999999999999399739135424 4.9999999999999999999399739135424451637890282671727096526710479005311754…
 89: 100.000000000 100.000000000000000000 +1.0000000000000000000000000000000e+02 4.9999999999999999999639843481255 4.9999999999999999999639843481254670982729845845769766098299530093665669…
 90: 100.000000000 100.000000000000000000 +1.0000000000000000000000000000000e+02 4.9999999999999999999783906088753 4.9999999999999999999783906088752802589636350954845922604598055525967896…
 91: 100.000000000 100.000000000000000000 +1.0000000000000000000000000000000e+02 4.9999999999999999999870343653252 4.9999999999999999999870343653251681553781250213965816223181428346555773…
 92: 100.000000000 100.000000000000000000 +1.0000000000000000000000000000000e+02 4.9999999999999999999922206191951 4.9999999999999999999922206191951008932268548399160464291660989824125886…
 93: 100.000000000 100.000000000000000000 +1.0000000000000000000000000000000e+02 4.9999999999999999999953323715171 4.9999999999999999999953323715170605359361056416977429415787361406993748…
 94: 100.000000000 100.000000000000000000 +1.0000000000000000000000000000000e+02 4.9999999999999999999971994229102 4.9999999999999999999971994229102363215616607706079671952157093083619619…
 95: 100.000000000 100.000000000000000000 +1.0000000000000000000000000000000e+02 4.9999999999999999999983196537461 4.9999999999999999999983196537461417929369955211769360320260739282306216…
 96: 100.000000000 100.000000000000000000 +1.0000000000000000000000000000000e+02 4.9999999999999999999989917922477 4.9999999999999999999989917922476850757621969738785376765784377601915608…
 97: 100.000000000 100.000000000000000000 +1.0000000000000000000000000000000e+02 4.9999999999999999999993950753486 4.9999999999999999999993950753486110454573180623491779865976682812204953…
 98: 100.000000000 100.000000000000000000 +1.0000000000000000000000000000000e+02 4.9999999999999999999996370452092 4.9999999999999999999996370452091666272743907934974467289928189937561311…
 99: 100.000000000 100.000000000000000000 +1.0000000000000000000000000000000e+02 4.9999999999999999999997822271255 4.9999999999999999999997822271254999763646344602901264147280098852591988…
--- PASS: TestMuller (0.00s)
PASS
ok   float128 0.011s


Be thoughtful in numerical computation.

Michael

--
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.

Michael Jones

unread,
Feb 2, 2020, 12:09:18 AM2/2/20
to golang-nuts
forgot the code...final test is what generates the report above.

Jason E. Aten

unread,
Feb 2, 2020, 5:10:04 AM2/2/20
to golang-nuts
Thanks Michael!

simon place

unread,
Feb 22, 2020, 2:50:52 PM2/22/20
to golang-nuts
absolutely, though even an epsilon is a bit of a hack IMHO. given the more ops you do the greater the potential discrepancy, and, i guess, you get a normal dist. of values, so any epsilon only has a probability of working, albeit potentially astronomically high probability.

so then why even have float equality in the/any language at all?

or might be nice if vet warned


On Sunday, 26 January 2020 03:34:11 UTC, Kurtis Rader wrote:
This is why you should never, ever, do a simple equality test involving a F.P. value derived from a calculation. You always have to apply an epsilon to define a range within which the two F.P. values should be considered equal.
On Sat, Jan 25, 2020 at 7:14 PM Jason E. Aten <j.e...@gmail.com> wrote:


I'd like to truncate a float64 to just 2 decimal places (in base 10), but math.Trunc is not helping me here... ideally I put 0.29 in and I get 0.29 out.
Suggestions?  Playground examples appreciated.

package main

import (
"fmt"
"math"
)

// truncate off everything after the last two decimals, no rounding.
func decimal2(x float64) float64 {
    return math.Trunc(x*100) / 100
}

func main() {
        x := 0.29
        y := decimal2(x)
fmt.Printf("x=%v -> y = %v", x, y) // prints x=0.29  ->  y=0.28
}

--
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 golan...@googlegroups.com.

robert engels

unread,
Feb 22, 2020, 2:58:09 PM2/22/20
to simon place, golang-nuts
float equality is useful for determining if “something changed” (e.g. the record has changed), you can also use float keys - the equality matters, the actual value not so much.

To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/229c73ce-88fb-46a0-a2ee-8454cbaa6ae5%40googlegroups.com.

simon place

unread,
Feb 22, 2020, 4:06:11 PM2/22/20
to golang-nuts
are you sure?

surely floats can have, say, a small number added, that depending of the value, sometimes doesn't change them and sometimes does. seems to me the same issue.

robert engels

unread,
Feb 22, 2020, 6:40:37 PM2/22/20
to simon place, golang-nuts
If the computation doesn’t change observable value - then it’s the same value… (when use as a key/equality) - which is why a better detection of change might be on the “value added” - but if that isn’t stored, you’ll be back to same spot.

To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/c37a2676-e6d2-4513-bb82-aad9b4755d80%40googlegroups.com.

Tom Mitchell

unread,
Feb 23, 2020, 4:56:32 AM2/23/20
to simon place, golang-nuts
On Sat, Feb 22, 2020 at 1:06 PM 'simon place' via golang-nuts <golan...@googlegroups.com> wrote:
are you sure?

surely floats can have, say, a small number added, that depending of the value, sometimes doesn't change them and sometimes does. seems to me the same issue.

On Saturday, 22 February 2020 19:58:09 UTC, robert engels wrote:
float equality is useful for determining if “something changed” 

Yes floats have operation limitations especially when the dynamic range of a data set (scale) is large and mixed.  Mix large and small floats and try simple operations like addition.  The random list will have one value, sort up and down to find two different answers.  Parallel computations with 1, 2, 3....many processors will have different net results depending on data in each block.

Printing converts float to string is not exact.  Truncating the string for display does not truncate the stored float. Comparing strings is not a comparison of the floating point data.

Compilers can make transformations and depending on hardware 80 internal bits for computations all in float registers can mismatch computations that spill in and out of registers or memory. Some 32 bit computation is done in 64 bit hardware and micro code extracts the 32 bit  value to store in memory, most  external data data representation (xdr) works but pay attention.

80 bit floating point hardware is clever but has pitfalls.  Especially with calling conventions.  

--
Tinny keyboard.. Mobile ... I am
Reply all
Reply to author
Forward
0 new messages