decimal.go 51 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904
  1. // Package decimal implements an arbitrary precision fixed-point decimal.
  2. //
  3. // The zero-value of a Decimal is 0, as you would expect.
  4. //
  5. // The best way to create a new Decimal is to use decimal.NewFromString, ex:
  6. //
  7. // n, err := decimal.NewFromString("-123.4567")
  8. // n.String() // output: "-123.4567"
  9. //
  10. // To use Decimal as part of a struct:
  11. //
  12. // type Struct struct {
  13. // Number Decimal
  14. // }
  15. //
  16. // Note: This can "only" represent numbers with a maximum of 2^31 digits after the decimal point.
  17. package decimal
  18. import (
  19. "database/sql/driver"
  20. "encoding/binary"
  21. "fmt"
  22. "math"
  23. "math/big"
  24. "regexp"
  25. "strconv"
  26. "strings"
  27. )
  28. // DivisionPrecision is the number of decimal places in the result when it
  29. // doesn't divide exactly.
  30. //
  31. // Example:
  32. //
  33. // d1 := decimal.NewFromFloat(2).Div(decimal.NewFromFloat(3))
  34. // d1.String() // output: "0.6666666666666667"
  35. // d2 := decimal.NewFromFloat(2).Div(decimal.NewFromFloat(30000))
  36. // d2.String() // output: "0.0000666666666667"
  37. // d3 := decimal.NewFromFloat(20000).Div(decimal.NewFromFloat(3))
  38. // d3.String() // output: "6666.6666666666666667"
  39. // decimal.DivisionPrecision = 3
  40. // d4 := decimal.NewFromFloat(2).Div(decimal.NewFromFloat(3))
  41. // d4.String() // output: "0.667"
  42. //
  43. var DivisionPrecision = 16
  44. // MarshalJSONWithoutQuotes should be set to true if you want the decimal to
  45. // be JSON marshaled as a number, instead of as a string.
  46. // WARNING: this is dangerous for decimals with many digits, since many JSON
  47. // unmarshallers (ex: Javascript's) will unmarshal JSON numbers to IEEE 754
  48. // double-precision floating point numbers, which means you can potentially
  49. // silently lose precision.
  50. var MarshalJSONWithoutQuotes = false
  51. // ExpMaxIterations specifies the maximum number of iterations needed to calculate
  52. // precise natural exponent value using ExpHullAbrham method.
  53. var ExpMaxIterations = 1000
  54. // Zero constant, to make computations faster.
  55. // Zero should never be compared with == or != directly, please use decimal.Equal or decimal.Cmp instead.
  56. var Zero = New(0, 1)
  57. var zeroInt = big.NewInt(0)
  58. var oneInt = big.NewInt(1)
  59. var twoInt = big.NewInt(2)
  60. var fourInt = big.NewInt(4)
  61. var fiveInt = big.NewInt(5)
  62. var tenInt = big.NewInt(10)
  63. var twentyInt = big.NewInt(20)
  64. var factorials = []Decimal{New(1, 0)}
  65. // Decimal represents a fixed-point decimal. It is immutable.
  66. // number = value * 10 ^ exp
  67. type Decimal struct {
  68. value *big.Int
  69. // NOTE(vadim): this must be an int32, because we cast it to float64 during
  70. // calculations. If exp is 64 bit, we might lose precision.
  71. // If we cared about being able to represent every possible decimal, we
  72. // could make exp a *big.Int but it would hurt performance and numbers
  73. // like that are unrealistic.
  74. exp int32
  75. }
  76. // New returns a new fixed-point decimal, value * 10 ^ exp.
  77. func New(value int64, exp int32) Decimal {
  78. return Decimal{
  79. value: big.NewInt(value),
  80. exp: exp,
  81. }
  82. }
  83. // NewFromInt converts a int64 to Decimal.
  84. //
  85. // Example:
  86. //
  87. // NewFromInt(123).String() // output: "123"
  88. // NewFromInt(-10).String() // output: "-10"
  89. func NewFromInt(value int64) Decimal {
  90. return Decimal{
  91. value: big.NewInt(value),
  92. exp: 0,
  93. }
  94. }
  95. // NewFromInt32 converts a int32 to Decimal.
  96. //
  97. // Example:
  98. //
  99. // NewFromInt(123).String() // output: "123"
  100. // NewFromInt(-10).String() // output: "-10"
  101. func NewFromInt32(value int32) Decimal {
  102. return Decimal{
  103. value: big.NewInt(int64(value)),
  104. exp: 0,
  105. }
  106. }
  107. // NewFromBigInt returns a new Decimal from a big.Int, value * 10 ^ exp
  108. func NewFromBigInt(value *big.Int, exp int32) Decimal {
  109. return Decimal{
  110. value: new(big.Int).Set(value),
  111. exp: exp,
  112. }
  113. }
  114. // NewFromString returns a new Decimal from a string representation.
  115. // Trailing zeroes are not trimmed.
  116. //
  117. // Example:
  118. //
  119. // d, err := NewFromString("-123.45")
  120. // d2, err := NewFromString(".0001")
  121. // d3, err := NewFromString("1.47000")
  122. //
  123. func NewFromString(value string) (Decimal, error) {
  124. originalInput := value
  125. var intString string
  126. var exp int64
  127. // Check if number is using scientific notation
  128. eIndex := strings.IndexAny(value, "Ee")
  129. if eIndex != -1 {
  130. expInt, err := strconv.ParseInt(value[eIndex+1:], 10, 32)
  131. if err != nil {
  132. if e, ok := err.(*strconv.NumError); ok && e.Err == strconv.ErrRange {
  133. return Decimal{}, fmt.Errorf("can't convert %s to decimal: fractional part too long", value)
  134. }
  135. return Decimal{}, fmt.Errorf("can't convert %s to decimal: exponent is not numeric", value)
  136. }
  137. value = value[:eIndex]
  138. exp = expInt
  139. }
  140. pIndex := -1
  141. vLen := len(value)
  142. for i := 0; i < vLen; i++ {
  143. if value[i] == '.' {
  144. if pIndex > -1 {
  145. return Decimal{}, fmt.Errorf("can't convert %s to decimal: too many .s", value)
  146. }
  147. pIndex = i
  148. }
  149. }
  150. if pIndex == -1 {
  151. // There is no decimal point, we can just parse the original string as
  152. // an int
  153. intString = value
  154. } else {
  155. if pIndex+1 < vLen {
  156. intString = value[:pIndex] + value[pIndex+1:]
  157. } else {
  158. intString = value[:pIndex]
  159. }
  160. expInt := -len(value[pIndex+1:])
  161. exp += int64(expInt)
  162. }
  163. var dValue *big.Int
  164. // strconv.ParseInt is faster than new(big.Int).SetString so this is just a shortcut for strings we know won't overflow
  165. if len(intString) <= 18 {
  166. parsed64, err := strconv.ParseInt(intString, 10, 64)
  167. if err != nil {
  168. return Decimal{}, fmt.Errorf("can't convert %s to decimal", value)
  169. }
  170. dValue = big.NewInt(parsed64)
  171. } else {
  172. dValue = new(big.Int)
  173. _, ok := dValue.SetString(intString, 10)
  174. if !ok {
  175. return Decimal{}, fmt.Errorf("can't convert %s to decimal", value)
  176. }
  177. }
  178. if exp < math.MinInt32 || exp > math.MaxInt32 {
  179. // NOTE(vadim): I doubt a string could realistically be this long
  180. return Decimal{}, fmt.Errorf("can't convert %s to decimal: fractional part too long", originalInput)
  181. }
  182. return Decimal{
  183. value: dValue,
  184. exp: int32(exp),
  185. }, nil
  186. }
  187. // NewFromFormattedString returns a new Decimal from a formatted string representation.
  188. // The second argument - replRegexp, is a regular expression that is used to find characters that should be
  189. // removed from given decimal string representation. All matched characters will be replaced with an empty string.
  190. //
  191. // Example:
  192. //
  193. // r := regexp.MustCompile("[$,]")
  194. // d1, err := NewFromFormattedString("$5,125.99", r)
  195. //
  196. // r2 := regexp.MustCompile("[_]")
  197. // d2, err := NewFromFormattedString("1_000_000", r2)
  198. //
  199. // r3 := regexp.MustCompile("[USD\\s]")
  200. // d3, err := NewFromFormattedString("5000 USD", r3)
  201. //
  202. func NewFromFormattedString(value string, replRegexp *regexp.Regexp) (Decimal, error) {
  203. parsedValue := replRegexp.ReplaceAllString(value, "")
  204. d, err := NewFromString(parsedValue)
  205. if err != nil {
  206. return Decimal{}, err
  207. }
  208. return d, nil
  209. }
  210. // RequireFromString returns a new Decimal from a string representation
  211. // or panics if NewFromString would have returned an error.
  212. //
  213. // Example:
  214. //
  215. // d := RequireFromString("-123.45")
  216. // d2 := RequireFromString(".0001")
  217. //
  218. func RequireFromString(value string) Decimal {
  219. dec, err := NewFromString(value)
  220. if err != nil {
  221. panic(err)
  222. }
  223. return dec
  224. }
  225. // NewFromFloat converts a float64 to Decimal.
  226. //
  227. // The converted number will contain the number of significant digits that can be
  228. // represented in a float with reliable roundtrip.
  229. // This is typically 15 digits, but may be more in some cases.
  230. // See https://www.exploringbinary.com/decimal-precision-of-binary-floating-point-numbers/ for more information.
  231. //
  232. // For slightly faster conversion, use NewFromFloatWithExponent where you can specify the precision in absolute terms.
  233. //
  234. // NOTE: this will panic on NaN, +/-inf
  235. func NewFromFloat(value float64) Decimal {
  236. if value == 0 {
  237. return New(0, 0)
  238. }
  239. return newFromFloat(value, math.Float64bits(value), &float64info)
  240. }
  241. // NewFromFloat32 converts a float32 to Decimal.
  242. //
  243. // The converted number will contain the number of significant digits that can be
  244. // represented in a float with reliable roundtrip.
  245. // This is typically 6-8 digits depending on the input.
  246. // See https://www.exploringbinary.com/decimal-precision-of-binary-floating-point-numbers/ for more information.
  247. //
  248. // For slightly faster conversion, use NewFromFloatWithExponent where you can specify the precision in absolute terms.
  249. //
  250. // NOTE: this will panic on NaN, +/-inf
  251. func NewFromFloat32(value float32) Decimal {
  252. if value == 0 {
  253. return New(0, 0)
  254. }
  255. // XOR is workaround for https://github.com/golang/go/issues/26285
  256. a := math.Float32bits(value) ^ 0x80808080
  257. return newFromFloat(float64(value), uint64(a)^0x80808080, &float32info)
  258. }
  259. func newFromFloat(val float64, bits uint64, flt *floatInfo) Decimal {
  260. if math.IsNaN(val) || math.IsInf(val, 0) {
  261. panic(fmt.Sprintf("Cannot create a Decimal from %v", val))
  262. }
  263. exp := int(bits>>flt.mantbits) & (1<<flt.expbits - 1)
  264. mant := bits & (uint64(1)<<flt.mantbits - 1)
  265. switch exp {
  266. case 0:
  267. // denormalized
  268. exp++
  269. default:
  270. // add implicit top bit
  271. mant |= uint64(1) << flt.mantbits
  272. }
  273. exp += flt.bias
  274. var d decimal
  275. d.Assign(mant)
  276. d.Shift(exp - int(flt.mantbits))
  277. d.neg = bits>>(flt.expbits+flt.mantbits) != 0
  278. roundShortest(&d, mant, exp, flt)
  279. // If less than 19 digits, we can do calculation in an int64.
  280. if d.nd < 19 {
  281. tmp := int64(0)
  282. m := int64(1)
  283. for i := d.nd - 1; i >= 0; i-- {
  284. tmp += m * int64(d.d[i]-'0')
  285. m *= 10
  286. }
  287. if d.neg {
  288. tmp *= -1
  289. }
  290. return Decimal{value: big.NewInt(tmp), exp: int32(d.dp) - int32(d.nd)}
  291. }
  292. dValue := new(big.Int)
  293. dValue, ok := dValue.SetString(string(d.d[:d.nd]), 10)
  294. if ok {
  295. return Decimal{value: dValue, exp: int32(d.dp) - int32(d.nd)}
  296. }
  297. return NewFromFloatWithExponent(val, int32(d.dp)-int32(d.nd))
  298. }
  299. // NewFromFloatWithExponent converts a float64 to Decimal, with an arbitrary
  300. // number of fractional digits.
  301. //
  302. // Example:
  303. //
  304. // NewFromFloatWithExponent(123.456, -2).String() // output: "123.46"
  305. //
  306. func NewFromFloatWithExponent(value float64, exp int32) Decimal {
  307. if math.IsNaN(value) || math.IsInf(value, 0) {
  308. panic(fmt.Sprintf("Cannot create a Decimal from %v", value))
  309. }
  310. bits := math.Float64bits(value)
  311. mant := bits & (1<<52 - 1)
  312. exp2 := int32((bits >> 52) & (1<<11 - 1))
  313. sign := bits >> 63
  314. if exp2 == 0 {
  315. // specials
  316. if mant == 0 {
  317. return Decimal{}
  318. }
  319. // subnormal
  320. exp2++
  321. } else {
  322. // normal
  323. mant |= 1 << 52
  324. }
  325. exp2 -= 1023 + 52
  326. // normalizing base-2 values
  327. for mant&1 == 0 {
  328. mant = mant >> 1
  329. exp2++
  330. }
  331. // maximum number of fractional base-10 digits to represent 2^N exactly cannot be more than -N if N<0
  332. if exp < 0 && exp < exp2 {
  333. if exp2 < 0 {
  334. exp = exp2
  335. } else {
  336. exp = 0
  337. }
  338. }
  339. // representing 10^M * 2^N as 5^M * 2^(M+N)
  340. exp2 -= exp
  341. temp := big.NewInt(1)
  342. dMant := big.NewInt(int64(mant))
  343. // applying 5^M
  344. if exp > 0 {
  345. temp = temp.SetInt64(int64(exp))
  346. temp = temp.Exp(fiveInt, temp, nil)
  347. } else if exp < 0 {
  348. temp = temp.SetInt64(-int64(exp))
  349. temp = temp.Exp(fiveInt, temp, nil)
  350. dMant = dMant.Mul(dMant, temp)
  351. temp = temp.SetUint64(1)
  352. }
  353. // applying 2^(M+N)
  354. if exp2 > 0 {
  355. dMant = dMant.Lsh(dMant, uint(exp2))
  356. } else if exp2 < 0 {
  357. temp = temp.Lsh(temp, uint(-exp2))
  358. }
  359. // rounding and downscaling
  360. if exp > 0 || exp2 < 0 {
  361. halfDown := new(big.Int).Rsh(temp, 1)
  362. dMant = dMant.Add(dMant, halfDown)
  363. dMant = dMant.Quo(dMant, temp)
  364. }
  365. if sign == 1 {
  366. dMant = dMant.Neg(dMant)
  367. }
  368. return Decimal{
  369. value: dMant,
  370. exp: exp,
  371. }
  372. }
  373. // Copy returns a copy of decimal with the same value and exponent, but a different pointer to value.
  374. func (d Decimal) Copy() Decimal {
  375. d.ensureInitialized()
  376. return Decimal{
  377. value: &(*d.value),
  378. exp: d.exp,
  379. }
  380. }
  381. // rescale returns a rescaled version of the decimal. Returned
  382. // decimal may be less precise if the given exponent is bigger
  383. // than the initial exponent of the Decimal.
  384. // NOTE: this will truncate, NOT round
  385. //
  386. // Example:
  387. //
  388. // d := New(12345, -4)
  389. // d2 := d.rescale(-1)
  390. // d3 := d2.rescale(-4)
  391. // println(d1)
  392. // println(d2)
  393. // println(d3)
  394. //
  395. // Output:
  396. //
  397. // 1.2345
  398. // 1.2
  399. // 1.2000
  400. //
  401. func (d Decimal) rescale(exp int32) Decimal {
  402. d.ensureInitialized()
  403. if d.exp == exp {
  404. return Decimal{
  405. new(big.Int).Set(d.value),
  406. d.exp,
  407. }
  408. }
  409. // NOTE(vadim): must convert exps to float64 before - to prevent overflow
  410. diff := math.Abs(float64(exp) - float64(d.exp))
  411. value := new(big.Int).Set(d.value)
  412. expScale := new(big.Int).Exp(tenInt, big.NewInt(int64(diff)), nil)
  413. if exp > d.exp {
  414. value = value.Quo(value, expScale)
  415. } else if exp < d.exp {
  416. value = value.Mul(value, expScale)
  417. }
  418. return Decimal{
  419. value: value,
  420. exp: exp,
  421. }
  422. }
  423. // Abs returns the absolute value of the decimal.
  424. func (d Decimal) Abs() Decimal {
  425. if !d.IsNegative() {
  426. return d
  427. }
  428. d.ensureInitialized()
  429. d2Value := new(big.Int).Abs(d.value)
  430. return Decimal{
  431. value: d2Value,
  432. exp: d.exp,
  433. }
  434. }
  435. // Add returns d + d2.
  436. func (d Decimal) Add(d2 Decimal) Decimal {
  437. rd, rd2 := RescalePair(d, d2)
  438. d3Value := new(big.Int).Add(rd.value, rd2.value)
  439. return Decimal{
  440. value: d3Value,
  441. exp: rd.exp,
  442. }
  443. }
  444. // Sub returns d - d2.
  445. func (d Decimal) Sub(d2 Decimal) Decimal {
  446. rd, rd2 := RescalePair(d, d2)
  447. d3Value := new(big.Int).Sub(rd.value, rd2.value)
  448. return Decimal{
  449. value: d3Value,
  450. exp: rd.exp,
  451. }
  452. }
  453. // Neg returns -d.
  454. func (d Decimal) Neg() Decimal {
  455. d.ensureInitialized()
  456. val := new(big.Int).Neg(d.value)
  457. return Decimal{
  458. value: val,
  459. exp: d.exp,
  460. }
  461. }
  462. // Mul returns d * d2.
  463. func (d Decimal) Mul(d2 Decimal) Decimal {
  464. d.ensureInitialized()
  465. d2.ensureInitialized()
  466. expInt64 := int64(d.exp) + int64(d2.exp)
  467. if expInt64 > math.MaxInt32 || expInt64 < math.MinInt32 {
  468. // NOTE(vadim): better to panic than give incorrect results, as
  469. // Decimals are usually used for money
  470. panic(fmt.Sprintf("exponent %v overflows an int32!", expInt64))
  471. }
  472. d3Value := new(big.Int).Mul(d.value, d2.value)
  473. return Decimal{
  474. value: d3Value,
  475. exp: int32(expInt64),
  476. }
  477. }
  478. // Shift shifts the decimal in base 10.
  479. // It shifts left when shift is positive and right if shift is negative.
  480. // In simpler terms, the given value for shift is added to the exponent
  481. // of the decimal.
  482. func (d Decimal) Shift(shift int32) Decimal {
  483. d.ensureInitialized()
  484. return Decimal{
  485. value: new(big.Int).Set(d.value),
  486. exp: d.exp + shift,
  487. }
  488. }
  489. // Div returns d / d2. If it doesn't divide exactly, the result will have
  490. // DivisionPrecision digits after the decimal point.
  491. func (d Decimal) Div(d2 Decimal) Decimal {
  492. return d.DivRound(d2, int32(DivisionPrecision))
  493. }
  494. // QuoRem does divsion with remainder
  495. // d.QuoRem(d2,precision) returns quotient q and remainder r such that
  496. // d = d2 * q + r, q an integer multiple of 10^(-precision)
  497. // 0 <= r < abs(d2) * 10 ^(-precision) if d>=0
  498. // 0 >= r > -abs(d2) * 10 ^(-precision) if d<0
  499. // Note that precision<0 is allowed as input.
  500. func (d Decimal) QuoRem(d2 Decimal, precision int32) (Decimal, Decimal) {
  501. d.ensureInitialized()
  502. d2.ensureInitialized()
  503. if d2.value.Sign() == 0 {
  504. panic("decimal division by 0")
  505. }
  506. scale := -precision
  507. e := int64(d.exp - d2.exp - scale)
  508. if e > math.MaxInt32 || e < math.MinInt32 {
  509. panic("overflow in decimal QuoRem")
  510. }
  511. var aa, bb, expo big.Int
  512. var scalerest int32
  513. // d = a 10^ea
  514. // d2 = b 10^eb
  515. if e < 0 {
  516. aa = *d.value
  517. expo.SetInt64(-e)
  518. bb.Exp(tenInt, &expo, nil)
  519. bb.Mul(d2.value, &bb)
  520. scalerest = d.exp
  521. // now aa = a
  522. // bb = b 10^(scale + eb - ea)
  523. } else {
  524. expo.SetInt64(e)
  525. aa.Exp(tenInt, &expo, nil)
  526. aa.Mul(d.value, &aa)
  527. bb = *d2.value
  528. scalerest = scale + d2.exp
  529. // now aa = a ^ (ea - eb - scale)
  530. // bb = b
  531. }
  532. var q, r big.Int
  533. q.QuoRem(&aa, &bb, &r)
  534. dq := Decimal{value: &q, exp: scale}
  535. dr := Decimal{value: &r, exp: scalerest}
  536. return dq, dr
  537. }
  538. // DivRound divides and rounds to a given precision
  539. // i.e. to an integer multiple of 10^(-precision)
  540. // for a positive quotient digit 5 is rounded up, away from 0
  541. // if the quotient is negative then digit 5 is rounded down, away from 0
  542. // Note that precision<0 is allowed as input.
  543. func (d Decimal) DivRound(d2 Decimal, precision int32) Decimal {
  544. // QuoRem already checks initialization
  545. q, r := d.QuoRem(d2, precision)
  546. // the actual rounding decision is based on comparing r*10^precision and d2/2
  547. // instead compare 2 r 10 ^precision and d2
  548. var rv2 big.Int
  549. rv2.Abs(r.value)
  550. rv2.Lsh(&rv2, 1)
  551. // now rv2 = abs(r.value) * 2
  552. r2 := Decimal{value: &rv2, exp: r.exp + precision}
  553. // r2 is now 2 * r * 10 ^ precision
  554. var c = r2.Cmp(d2.Abs())
  555. if c < 0 {
  556. return q
  557. }
  558. if d.value.Sign()*d2.value.Sign() < 0 {
  559. return q.Sub(New(1, -precision))
  560. }
  561. return q.Add(New(1, -precision))
  562. }
  563. // Mod returns d % d2.
  564. func (d Decimal) Mod(d2 Decimal) Decimal {
  565. quo := d.Div(d2).Truncate(0)
  566. return d.Sub(d2.Mul(quo))
  567. }
  568. // Pow returns d to the power d2
  569. func (d Decimal) Pow(d2 Decimal) Decimal {
  570. var temp Decimal
  571. if d2.IntPart() == 0 {
  572. return NewFromFloat(1)
  573. }
  574. temp = d.Pow(d2.Div(NewFromFloat(2)))
  575. if d2.IntPart()%2 == 0 {
  576. return temp.Mul(temp)
  577. }
  578. if d2.IntPart() > 0 {
  579. return temp.Mul(temp).Mul(d)
  580. }
  581. return temp.Mul(temp).Div(d)
  582. }
  583. // ExpHullAbrham calculates the natural exponent of decimal (e to the power of d) using Hull-Abraham algorithm.
  584. // OverallPrecision argument specifies the overall precision of the result (integer part + decimal part).
  585. //
  586. // ExpHullAbrham is faster than ExpTaylor for small precision values, but it is much slower for large precision values.
  587. //
  588. // Example:
  589. //
  590. // NewFromFloat(26.1).ExpHullAbrham(2).String() // output: "220000000000"
  591. // NewFromFloat(26.1).ExpHullAbrham(20).String() // output: "216314672147.05767284"
  592. //
  593. func (d Decimal) ExpHullAbrham(overallPrecision uint32) (Decimal, error) {
  594. // Algorithm based on Variable precision exponential function.
  595. // ACM Transactions on Mathematical Software by T. E. Hull & A. Abrham.
  596. if d.IsZero() {
  597. return Decimal{oneInt, 0}, nil
  598. }
  599. currentPrecision := overallPrecision
  600. // Algorithm does not work if currentPrecision * 23 < |x|.
  601. // Precision is automatically increased in such cases, so the value can be calculated precisely.
  602. // If newly calculated precision is higher than ExpMaxIterations the currentPrecision will not be changed.
  603. f := d.Abs().InexactFloat64()
  604. if ncp := f / 23; ncp > float64(currentPrecision) && ncp < float64(ExpMaxIterations) {
  605. currentPrecision = uint32(math.Ceil(ncp))
  606. }
  607. // fail if abs(d) beyond an over/underflow threshold
  608. overflowThreshold := New(23*int64(currentPrecision), 0)
  609. if d.Abs().Cmp(overflowThreshold) > 0 {
  610. return Decimal{}, fmt.Errorf("over/underflow threshold, exp(x) cannot be calculated precisely")
  611. }
  612. // Return 1 if abs(d) small enough; this also avoids later over/underflow
  613. overflowThreshold2 := New(9, -int32(currentPrecision)-1)
  614. if d.Abs().Cmp(overflowThreshold2) <= 0 {
  615. return Decimal{oneInt, d.exp}, nil
  616. }
  617. // t is the smallest integer >= 0 such that the corresponding abs(d/k) < 1
  618. t := d.exp + int32(d.NumDigits()) // Add d.NumDigits because the paper assumes that d.value [0.1, 1)
  619. if t < 0 {
  620. t = 0
  621. }
  622. k := New(1, t) // reduction factor
  623. r := Decimal{new(big.Int).Set(d.value), d.exp - t} // reduced argument
  624. p := int32(currentPrecision) + t + 2 // precision for calculating the sum
  625. // Determine n, the number of therms for calculating sum
  626. // use first Newton step (1.435p - 1.182) / log10(p/abs(r))
  627. // for solving appropriate equation, along with directed
  628. // roundings and simple rational bound for log10(p/abs(r))
  629. rf := r.Abs().InexactFloat64()
  630. pf := float64(p)
  631. nf := math.Ceil((1.453*pf - 1.182) / math.Log10(pf/rf))
  632. if nf > float64(ExpMaxIterations) || math.IsNaN(nf) {
  633. return Decimal{}, fmt.Errorf("exact value cannot be calculated in <=ExpMaxIterations iterations")
  634. }
  635. n := int64(nf)
  636. tmp := New(0, 0)
  637. sum := New(1, 0)
  638. one := New(1, 0)
  639. for i := n - 1; i > 0; i-- {
  640. tmp.value.SetInt64(i)
  641. sum = sum.Mul(r.DivRound(tmp, p))
  642. sum = sum.Add(one)
  643. }
  644. ki := k.IntPart()
  645. res := New(1, 0)
  646. for i := ki; i > 0; i-- {
  647. res = res.Mul(sum)
  648. }
  649. resNumDigits := int32(res.NumDigits())
  650. var roundDigits int32
  651. if resNumDigits > abs(res.exp) {
  652. roundDigits = int32(currentPrecision) - resNumDigits - res.exp
  653. } else {
  654. roundDigits = int32(currentPrecision)
  655. }
  656. res = res.Round(roundDigits)
  657. return res, nil
  658. }
  659. // ExpTaylor calculates the natural exponent of decimal (e to the power of d) using Taylor series expansion.
  660. // Precision argument specifies how precise the result must be (number of digits after decimal point).
  661. // Negative precision is allowed.
  662. //
  663. // ExpTaylor is much faster for large precision values than ExpHullAbrham.
  664. //
  665. // Example:
  666. //
  667. // d, err := NewFromFloat(26.1).ExpTaylor(2).String()
  668. // d.String() // output: "216314672147.06"
  669. //
  670. // NewFromFloat(26.1).ExpTaylor(20).String()
  671. // d.String() // output: "216314672147.05767284062928674083"
  672. //
  673. // NewFromFloat(26.1).ExpTaylor(-10).String()
  674. // d.String() // output: "220000000000"
  675. //
  676. func (d Decimal) ExpTaylor(precision int32) (Decimal, error) {
  677. // Note(mwoss): Implementation can be optimized by exclusively using big.Int API only
  678. if d.IsZero() {
  679. return Decimal{oneInt, 0}.Round(precision), nil
  680. }
  681. var epsilon Decimal
  682. var divPrecision int32
  683. if precision < 0 {
  684. epsilon = New(1, -1)
  685. divPrecision = 8
  686. } else {
  687. epsilon = New(1, -precision-1)
  688. divPrecision = precision + 1
  689. }
  690. decAbs := d.Abs()
  691. pow := d.Abs()
  692. factorial := New(1, 0)
  693. result := New(1, 0)
  694. for i := int64(1); ; {
  695. step := pow.DivRound(factorial, divPrecision)
  696. result = result.Add(step)
  697. // Stop Taylor series when current step is smaller than epsilon
  698. if step.Cmp(epsilon) < 0 {
  699. break
  700. }
  701. pow = pow.Mul(decAbs)
  702. i++
  703. // Calculate next factorial number or retrieve cached value
  704. if len(factorials) >= int(i) && !factorials[i-1].IsZero() {
  705. factorial = factorials[i-1]
  706. } else {
  707. // To avoid any race conditions, firstly the zero value is appended to a slice to create
  708. // a spot for newly calculated factorial. After that, the zero value is replaced by calculated
  709. // factorial using the index notation.
  710. factorial = factorials[i-2].Mul(New(i, 0))
  711. factorials = append(factorials, Zero)
  712. factorials[i-1] = factorial
  713. }
  714. }
  715. if d.Sign() < 0 {
  716. result = New(1, 0).DivRound(result, precision+1)
  717. }
  718. result = result.Round(precision)
  719. return result, nil
  720. }
  721. // NumDigits returns the number of digits of the decimal coefficient (d.Value)
  722. // Note: Current implementation is extremely slow for large decimals and/or decimals with large fractional part
  723. func (d Decimal) NumDigits() int {
  724. // Note(mwoss): It can be optimized, unnecessary cast of big.Int to string
  725. if d.IsNegative() {
  726. return len(d.value.String()) - 1
  727. }
  728. return len(d.value.String())
  729. }
  730. // IsInteger returns true when decimal can be represented as an integer value, otherwise, it returns false.
  731. func (d Decimal) IsInteger() bool {
  732. // The most typical case, all decimal with exponent higher or equal 0 can be represented as integer
  733. if d.exp >= 0 {
  734. return true
  735. }
  736. // When the exponent is negative we have to check every number after the decimal place
  737. // If all of them are zeroes, we are sure that given decimal can be represented as an integer
  738. var r big.Int
  739. q := new(big.Int).Set(d.value)
  740. for z := abs(d.exp); z > 0; z-- {
  741. q.QuoRem(q, tenInt, &r)
  742. if r.Cmp(zeroInt) != 0 {
  743. return false
  744. }
  745. }
  746. return true
  747. }
  748. // Abs calculates absolute value of any int32. Used for calculating absolute value of decimal's exponent.
  749. func abs(n int32) int32 {
  750. if n < 0 {
  751. return -n
  752. }
  753. return n
  754. }
  755. // Cmp compares the numbers represented by d and d2 and returns:
  756. //
  757. // -1 if d < d2
  758. // 0 if d == d2
  759. // +1 if d > d2
  760. //
  761. func (d Decimal) Cmp(d2 Decimal) int {
  762. d.ensureInitialized()
  763. d2.ensureInitialized()
  764. if d.exp == d2.exp {
  765. return d.value.Cmp(d2.value)
  766. }
  767. rd, rd2 := RescalePair(d, d2)
  768. return rd.value.Cmp(rd2.value)
  769. }
  770. // Equal returns whether the numbers represented by d and d2 are equal.
  771. func (d Decimal) Equal(d2 Decimal) bool {
  772. return d.Cmp(d2) == 0
  773. }
  774. // Equals is deprecated, please use Equal method instead
  775. func (d Decimal) Equals(d2 Decimal) bool {
  776. return d.Equal(d2)
  777. }
  778. // GreaterThan (GT) returns true when d is greater than d2.
  779. func (d Decimal) GreaterThan(d2 Decimal) bool {
  780. return d.Cmp(d2) == 1
  781. }
  782. // GreaterThanOrEqual (GTE) returns true when d is greater than or equal to d2.
  783. func (d Decimal) GreaterThanOrEqual(d2 Decimal) bool {
  784. cmp := d.Cmp(d2)
  785. return cmp == 1 || cmp == 0
  786. }
  787. // LessThan (LT) returns true when d is less than d2.
  788. func (d Decimal) LessThan(d2 Decimal) bool {
  789. return d.Cmp(d2) == -1
  790. }
  791. // LessThanOrEqual (LTE) returns true when d is less than or equal to d2.
  792. func (d Decimal) LessThanOrEqual(d2 Decimal) bool {
  793. cmp := d.Cmp(d2)
  794. return cmp == -1 || cmp == 0
  795. }
  796. // Sign returns:
  797. //
  798. // -1 if d < 0
  799. // 0 if d == 0
  800. // +1 if d > 0
  801. //
  802. func (d Decimal) Sign() int {
  803. if d.value == nil {
  804. return 0
  805. }
  806. return d.value.Sign()
  807. }
  808. // IsPositive return
  809. //
  810. // true if d > 0
  811. // false if d == 0
  812. // false if d < 0
  813. func (d Decimal) IsPositive() bool {
  814. return d.Sign() == 1
  815. }
  816. // IsNegative return
  817. //
  818. // true if d < 0
  819. // false if d == 0
  820. // false if d > 0
  821. func (d Decimal) IsNegative() bool {
  822. return d.Sign() == -1
  823. }
  824. // IsZero return
  825. //
  826. // true if d == 0
  827. // false if d > 0
  828. // false if d < 0
  829. func (d Decimal) IsZero() bool {
  830. return d.Sign() == 0
  831. }
  832. // Exponent returns the exponent, or scale component of the decimal.
  833. func (d Decimal) Exponent() int32 {
  834. return d.exp
  835. }
  836. // Coefficient returns the coefficient of the decimal. It is scaled by 10^Exponent()
  837. func (d Decimal) Coefficient() *big.Int {
  838. d.ensureInitialized()
  839. // we copy the coefficient so that mutating the result does not mutate the Decimal.
  840. return new(big.Int).Set(d.value)
  841. }
  842. // CoefficientInt64 returns the coefficient of the decimal as int64. It is scaled by 10^Exponent()
  843. // If coefficient cannot be represented in an int64, the result will be undefined.
  844. func (d Decimal) CoefficientInt64() int64 {
  845. d.ensureInitialized()
  846. return d.value.Int64()
  847. }
  848. // IntPart returns the integer component of the decimal.
  849. func (d Decimal) IntPart() int64 {
  850. scaledD := d.rescale(0)
  851. return scaledD.value.Int64()
  852. }
  853. // BigInt returns integer component of the decimal as a BigInt.
  854. func (d Decimal) BigInt() *big.Int {
  855. scaledD := d.rescale(0)
  856. i := &big.Int{}
  857. i.SetString(scaledD.String(), 10)
  858. return i
  859. }
  860. // BigFloat returns decimal as BigFloat.
  861. // Be aware that casting decimal to BigFloat might cause a loss of precision.
  862. func (d Decimal) BigFloat() *big.Float {
  863. f := &big.Float{}
  864. f.SetString(d.String())
  865. return f
  866. }
  867. // Rat returns a rational number representation of the decimal.
  868. func (d Decimal) Rat() *big.Rat {
  869. d.ensureInitialized()
  870. if d.exp <= 0 {
  871. // NOTE(vadim): must negate after casting to prevent int32 overflow
  872. denom := new(big.Int).Exp(tenInt, big.NewInt(-int64(d.exp)), nil)
  873. return new(big.Rat).SetFrac(d.value, denom)
  874. }
  875. mul := new(big.Int).Exp(tenInt, big.NewInt(int64(d.exp)), nil)
  876. num := new(big.Int).Mul(d.value, mul)
  877. return new(big.Rat).SetFrac(num, oneInt)
  878. }
  879. // Float64 returns the nearest float64 value for d and a bool indicating
  880. // whether f represents d exactly.
  881. // For more details, see the documentation for big.Rat.Float64
  882. func (d Decimal) Float64() (f float64, exact bool) {
  883. return d.Rat().Float64()
  884. }
  885. // InexactFloat64 returns the nearest float64 value for d.
  886. // It doesn't indicate if the returned value represents d exactly.
  887. func (d Decimal) InexactFloat64() float64 {
  888. f, _ := d.Float64()
  889. return f
  890. }
  891. // String returns the string representation of the decimal
  892. // with the fixed point.
  893. //
  894. // Example:
  895. //
  896. // d := New(-12345, -3)
  897. // println(d.String())
  898. //
  899. // Output:
  900. //
  901. // -12.345
  902. //
  903. func (d Decimal) String() string {
  904. return d.string(true)
  905. }
  906. // StringFixed returns a rounded fixed-point string with places digits after
  907. // the decimal point.
  908. //
  909. // Example:
  910. //
  911. // NewFromFloat(0).StringFixed(2) // output: "0.00"
  912. // NewFromFloat(0).StringFixed(0) // output: "0"
  913. // NewFromFloat(5.45).StringFixed(0) // output: "5"
  914. // NewFromFloat(5.45).StringFixed(1) // output: "5.5"
  915. // NewFromFloat(5.45).StringFixed(2) // output: "5.45"
  916. // NewFromFloat(5.45).StringFixed(3) // output: "5.450"
  917. // NewFromFloat(545).StringFixed(-1) // output: "550"
  918. //
  919. func (d Decimal) StringFixed(places int32) string {
  920. rounded := d.Round(places)
  921. return rounded.string(false)
  922. }
  923. // StringFixedBank returns a banker rounded fixed-point string with places digits
  924. // after the decimal point.
  925. //
  926. // Example:
  927. //
  928. // NewFromFloat(0).StringFixedBank(2) // output: "0.00"
  929. // NewFromFloat(0).StringFixedBank(0) // output: "0"
  930. // NewFromFloat(5.45).StringFixedBank(0) // output: "5"
  931. // NewFromFloat(5.45).StringFixedBank(1) // output: "5.4"
  932. // NewFromFloat(5.45).StringFixedBank(2) // output: "5.45"
  933. // NewFromFloat(5.45).StringFixedBank(3) // output: "5.450"
  934. // NewFromFloat(545).StringFixedBank(-1) // output: "540"
  935. //
  936. func (d Decimal) StringFixedBank(places int32) string {
  937. rounded := d.RoundBank(places)
  938. return rounded.string(false)
  939. }
  940. // StringFixedCash returns a Swedish/Cash rounded fixed-point string. For
  941. // more details see the documentation at function RoundCash.
  942. func (d Decimal) StringFixedCash(interval uint8) string {
  943. rounded := d.RoundCash(interval)
  944. return rounded.string(false)
  945. }
  946. // Round rounds the decimal to places decimal places.
  947. // If places < 0, it will round the integer part to the nearest 10^(-places).
  948. //
  949. // Example:
  950. //
  951. // NewFromFloat(5.45).Round(1).String() // output: "5.5"
  952. // NewFromFloat(545).Round(-1).String() // output: "550"
  953. //
  954. func (d Decimal) Round(places int32) Decimal {
  955. if d.exp == -places {
  956. return d
  957. }
  958. // truncate to places + 1
  959. ret := d.rescale(-places - 1)
  960. // add sign(d) * 0.5
  961. if ret.value.Sign() < 0 {
  962. ret.value.Sub(ret.value, fiveInt)
  963. } else {
  964. ret.value.Add(ret.value, fiveInt)
  965. }
  966. // floor for positive numbers, ceil for negative numbers
  967. _, m := ret.value.DivMod(ret.value, tenInt, new(big.Int))
  968. ret.exp++
  969. if ret.value.Sign() < 0 && m.Cmp(zeroInt) != 0 {
  970. ret.value.Add(ret.value, oneInt)
  971. }
  972. return ret
  973. }
  974. // RoundCeil rounds the decimal towards +infinity.
  975. //
  976. // Example:
  977. //
  978. // NewFromFloat(545).RoundCeil(-2).String() // output: "600"
  979. // NewFromFloat(500).RoundCeil(-2).String() // output: "500"
  980. // NewFromFloat(1.1001).RoundCeil(2).String() // output: "1.11"
  981. // NewFromFloat(-1.454).RoundCeil(1).String() // output: "-1.5"
  982. //
  983. func (d Decimal) RoundCeil(places int32) Decimal {
  984. if d.exp >= -places {
  985. return d
  986. }
  987. rescaled := d.rescale(-places)
  988. if d.Equal(rescaled) {
  989. return d
  990. }
  991. if d.value.Sign() > 0 {
  992. rescaled.value.Add(rescaled.value, oneInt)
  993. }
  994. return rescaled
  995. }
  996. // RoundFloor rounds the decimal towards -infinity.
  997. //
  998. // Example:
  999. //
  1000. // NewFromFloat(545).RoundFloor(-2).String() // output: "500"
  1001. // NewFromFloat(-500).RoundFloor(-2).String() // output: "-500"
  1002. // NewFromFloat(1.1001).RoundFloor(2).String() // output: "1.1"
  1003. // NewFromFloat(-1.454).RoundFloor(1).String() // output: "-1.4"
  1004. //
  1005. func (d Decimal) RoundFloor(places int32) Decimal {
  1006. if d.exp >= -places {
  1007. return d
  1008. }
  1009. rescaled := d.rescale(-places)
  1010. if d.Equal(rescaled) {
  1011. return d
  1012. }
  1013. if d.value.Sign() < 0 {
  1014. rescaled.value.Sub(rescaled.value, oneInt)
  1015. }
  1016. return rescaled
  1017. }
  1018. // RoundUp rounds the decimal away from zero.
  1019. //
  1020. // Example:
  1021. //
  1022. // NewFromFloat(545).RoundUp(-2).String() // output: "600"
  1023. // NewFromFloat(500).RoundUp(-2).String() // output: "500"
  1024. // NewFromFloat(1.1001).RoundUp(2).String() // output: "1.11"
  1025. // NewFromFloat(-1.454).RoundUp(1).String() // output: "-1.4"
  1026. //
  1027. func (d Decimal) RoundUp(places int32) Decimal {
  1028. if d.exp >= -places {
  1029. return d
  1030. }
  1031. rescaled := d.rescale(-places)
  1032. if d.Equal(rescaled) {
  1033. return d
  1034. }
  1035. if d.value.Sign() > 0 {
  1036. rescaled.value.Add(rescaled.value, oneInt)
  1037. } else if d.value.Sign() < 0 {
  1038. rescaled.value.Sub(rescaled.value, oneInt)
  1039. }
  1040. return rescaled
  1041. }
  1042. // RoundDown rounds the decimal towards zero.
  1043. //
  1044. // Example:
  1045. //
  1046. // NewFromFloat(545).RoundDown(-2).String() // output: "500"
  1047. // NewFromFloat(-500).RoundDown(-2).String() // output: "-500"
  1048. // NewFromFloat(1.1001).RoundDown(2).String() // output: "1.1"
  1049. // NewFromFloat(-1.454).RoundDown(1).String() // output: "-1.5"
  1050. //
  1051. func (d Decimal) RoundDown(places int32) Decimal {
  1052. if d.exp >= -places {
  1053. return d
  1054. }
  1055. rescaled := d.rescale(-places)
  1056. if d.Equal(rescaled) {
  1057. return d
  1058. }
  1059. return rescaled
  1060. }
  1061. // RoundBank rounds the decimal to places decimal places.
  1062. // If the final digit to round is equidistant from the nearest two integers the
  1063. // rounded value is taken as the even number
  1064. //
  1065. // If places < 0, it will round the integer part to the nearest 10^(-places).
  1066. //
  1067. // Examples:
  1068. //
  1069. // NewFromFloat(5.45).RoundBank(1).String() // output: "5.4"
  1070. // NewFromFloat(545).RoundBank(-1).String() // output: "540"
  1071. // NewFromFloat(5.46).RoundBank(1).String() // output: "5.5"
  1072. // NewFromFloat(546).RoundBank(-1).String() // output: "550"
  1073. // NewFromFloat(5.55).RoundBank(1).String() // output: "5.6"
  1074. // NewFromFloat(555).RoundBank(-1).String() // output: "560"
  1075. //
  1076. func (d Decimal) RoundBank(places int32) Decimal {
  1077. round := d.Round(places)
  1078. remainder := d.Sub(round).Abs()
  1079. half := New(5, -places-1)
  1080. if remainder.Cmp(half) == 0 && round.value.Bit(0) != 0 {
  1081. if round.value.Sign() < 0 {
  1082. round.value.Add(round.value, oneInt)
  1083. } else {
  1084. round.value.Sub(round.value, oneInt)
  1085. }
  1086. }
  1087. return round
  1088. }
  1089. // RoundCash aka Cash/Penny/öre rounding rounds decimal to a specific
  1090. // interval. The amount payable for a cash transaction is rounded to the nearest
  1091. // multiple of the minimum currency unit available. The following intervals are
  1092. // available: 5, 10, 25, 50 and 100; any other number throws a panic.
  1093. // 5: 5 cent rounding 3.43 => 3.45
  1094. // 10: 10 cent rounding 3.45 => 3.50 (5 gets rounded up)
  1095. // 25: 25 cent rounding 3.41 => 3.50
  1096. // 50: 50 cent rounding 3.75 => 4.00
  1097. // 100: 100 cent rounding 3.50 => 4.00
  1098. // For more details: https://en.wikipedia.org/wiki/Cash_rounding
  1099. func (d Decimal) RoundCash(interval uint8) Decimal {
  1100. var iVal *big.Int
  1101. switch interval {
  1102. case 5:
  1103. iVal = twentyInt
  1104. case 10:
  1105. iVal = tenInt
  1106. case 25:
  1107. iVal = fourInt
  1108. case 50:
  1109. iVal = twoInt
  1110. case 100:
  1111. iVal = oneInt
  1112. default:
  1113. panic(fmt.Sprintf("Decimal does not support this Cash rounding interval `%d`. Supported: 5, 10, 25, 50, 100", interval))
  1114. }
  1115. dVal := Decimal{
  1116. value: iVal,
  1117. }
  1118. // TODO: optimize those calculations to reduce the high allocations (~29 allocs).
  1119. return d.Mul(dVal).Round(0).Div(dVal).Truncate(2)
  1120. }
  1121. // Floor returns the nearest integer value less than or equal to d.
  1122. func (d Decimal) Floor() Decimal {
  1123. d.ensureInitialized()
  1124. if d.exp >= 0 {
  1125. return d
  1126. }
  1127. exp := big.NewInt(10)
  1128. // NOTE(vadim): must negate after casting to prevent int32 overflow
  1129. exp.Exp(exp, big.NewInt(-int64(d.exp)), nil)
  1130. z := new(big.Int).Div(d.value, exp)
  1131. return Decimal{value: z, exp: 0}
  1132. }
  1133. // Ceil returns the nearest integer value greater than or equal to d.
  1134. func (d Decimal) Ceil() Decimal {
  1135. d.ensureInitialized()
  1136. if d.exp >= 0 {
  1137. return d
  1138. }
  1139. exp := big.NewInt(10)
  1140. // NOTE(vadim): must negate after casting to prevent int32 overflow
  1141. exp.Exp(exp, big.NewInt(-int64(d.exp)), nil)
  1142. z, m := new(big.Int).DivMod(d.value, exp, new(big.Int))
  1143. if m.Cmp(zeroInt) != 0 {
  1144. z.Add(z, oneInt)
  1145. }
  1146. return Decimal{value: z, exp: 0}
  1147. }
  1148. // Truncate truncates off digits from the number, without rounding.
  1149. //
  1150. // NOTE: precision is the last digit that will not be truncated (must be >= 0).
  1151. //
  1152. // Example:
  1153. //
  1154. // decimal.NewFromString("123.456").Truncate(2).String() // "123.45"
  1155. //
  1156. func (d Decimal) Truncate(precision int32) Decimal {
  1157. d.ensureInitialized()
  1158. if precision >= 0 && -precision > d.exp {
  1159. return d.rescale(-precision)
  1160. }
  1161. return d
  1162. }
  1163. // UnmarshalJSON implements the json.Unmarshaler interface.
  1164. func (d *Decimal) UnmarshalJSON(decimalBytes []byte) error {
  1165. if string(decimalBytes) == "null" {
  1166. return nil
  1167. }
  1168. str, err := unquoteIfQuoted(decimalBytes)
  1169. if err != nil {
  1170. return fmt.Errorf("error decoding string '%s': %s", decimalBytes, err)
  1171. }
  1172. decimal, err := NewFromString(str)
  1173. *d = decimal
  1174. if err != nil {
  1175. return fmt.Errorf("error decoding string '%s': %s", str, err)
  1176. }
  1177. return nil
  1178. }
  1179. // MarshalJSON implements the json.Marshaler interface.
  1180. func (d Decimal) MarshalJSON() ([]byte, error) {
  1181. var str string
  1182. if MarshalJSONWithoutQuotes {
  1183. str = d.String()
  1184. } else {
  1185. str = "\"" + d.String() + "\""
  1186. }
  1187. return []byte(str), nil
  1188. }
  1189. // UnmarshalBinary implements the encoding.BinaryUnmarshaler interface. As a string representation
  1190. // is already used when encoding to text, this method stores that string as []byte
  1191. func (d *Decimal) UnmarshalBinary(data []byte) error {
  1192. // Verify we have at least 4 bytes for the exponent. The GOB encoded value
  1193. // may be empty.
  1194. if len(data) < 4 {
  1195. return fmt.Errorf("error decoding binary %v: expected at least 4 bytes, got %d", data, len(data))
  1196. }
  1197. // Extract the exponent
  1198. d.exp = int32(binary.BigEndian.Uint32(data[:4]))
  1199. // Extract the value
  1200. d.value = new(big.Int)
  1201. if err := d.value.GobDecode(data[4:]); err != nil {
  1202. return fmt.Errorf("error decoding binary %v: %s", data, err)
  1203. }
  1204. return nil
  1205. }
  1206. // MarshalBinary implements the encoding.BinaryMarshaler interface.
  1207. func (d Decimal) MarshalBinary() (data []byte, err error) {
  1208. // Write the exponent first since it's a fixed size
  1209. v1 := make([]byte, 4)
  1210. binary.BigEndian.PutUint32(v1, uint32(d.exp))
  1211. // Add the value
  1212. var v2 []byte
  1213. if v2, err = d.value.GobEncode(); err != nil {
  1214. return
  1215. }
  1216. // Return the byte array
  1217. data = append(v1, v2...)
  1218. return
  1219. }
  1220. // Scan implements the sql.Scanner interface for database deserialization.
  1221. func (d *Decimal) Scan(value interface{}) error {
  1222. // first try to see if the data is stored in database as a Numeric datatype
  1223. switch v := value.(type) {
  1224. case float32:
  1225. *d = NewFromFloat(float64(v))
  1226. return nil
  1227. case float64:
  1228. // numeric in sqlite3 sends us float64
  1229. *d = NewFromFloat(v)
  1230. return nil
  1231. case int64:
  1232. // at least in sqlite3 when the value is 0 in db, the data is sent
  1233. // to us as an int64 instead of a float64 ...
  1234. *d = New(v, 0)
  1235. return nil
  1236. default:
  1237. // default is trying to interpret value stored as string
  1238. str, err := unquoteIfQuoted(v)
  1239. if err != nil {
  1240. return err
  1241. }
  1242. *d, err = NewFromString(str)
  1243. return err
  1244. }
  1245. }
  1246. // Value implements the driver.Valuer interface for database serialization.
  1247. func (d Decimal) Value() (driver.Value, error) {
  1248. return d.String(), nil
  1249. }
  1250. // UnmarshalText implements the encoding.TextUnmarshaler interface for XML
  1251. // deserialization.
  1252. func (d *Decimal) UnmarshalText(text []byte) error {
  1253. str := string(text)
  1254. dec, err := NewFromString(str)
  1255. *d = dec
  1256. if err != nil {
  1257. return fmt.Errorf("error decoding string '%s': %s", str, err)
  1258. }
  1259. return nil
  1260. }
  1261. // MarshalText implements the encoding.TextMarshaler interface for XML
  1262. // serialization.
  1263. func (d Decimal) MarshalText() (text []byte, err error) {
  1264. return []byte(d.String()), nil
  1265. }
  1266. // GobEncode implements the gob.GobEncoder interface for gob serialization.
  1267. func (d Decimal) GobEncode() ([]byte, error) {
  1268. return d.MarshalBinary()
  1269. }
  1270. // GobDecode implements the gob.GobDecoder interface for gob serialization.
  1271. func (d *Decimal) GobDecode(data []byte) error {
  1272. return d.UnmarshalBinary(data)
  1273. }
  1274. // StringScaled first scales the decimal then calls .String() on it.
  1275. // NOTE: buggy, unintuitive, and DEPRECATED! Use StringFixed instead.
  1276. func (d Decimal) StringScaled(exp int32) string {
  1277. return d.rescale(exp).String()
  1278. }
  1279. func (d Decimal) string(trimTrailingZeros bool) string {
  1280. if d.exp >= 0 {
  1281. return d.rescale(0).value.String()
  1282. }
  1283. abs := new(big.Int).Abs(d.value)
  1284. str := abs.String()
  1285. var intPart, fractionalPart string
  1286. // NOTE(vadim): this cast to int will cause bugs if d.exp == INT_MIN
  1287. // and you are on a 32-bit machine. Won't fix this super-edge case.
  1288. dExpInt := int(d.exp)
  1289. if len(str) > -dExpInt {
  1290. intPart = str[:len(str)+dExpInt]
  1291. fractionalPart = str[len(str)+dExpInt:]
  1292. } else {
  1293. intPart = "0"
  1294. num0s := -dExpInt - len(str)
  1295. fractionalPart = strings.Repeat("0", num0s) + str
  1296. }
  1297. if trimTrailingZeros {
  1298. i := len(fractionalPart) - 1
  1299. for ; i >= 0; i-- {
  1300. if fractionalPart[i] != '0' {
  1301. break
  1302. }
  1303. }
  1304. fractionalPart = fractionalPart[:i+1]
  1305. }
  1306. number := intPart
  1307. if len(fractionalPart) > 0 {
  1308. number += "." + fractionalPart
  1309. }
  1310. if d.value.Sign() < 0 {
  1311. return "-" + number
  1312. }
  1313. return number
  1314. }
  1315. func (d *Decimal) ensureInitialized() {
  1316. if d.value == nil {
  1317. d.value = new(big.Int)
  1318. }
  1319. }
  1320. // Min returns the smallest Decimal that was passed in the arguments.
  1321. //
  1322. // To call this function with an array, you must do:
  1323. //
  1324. // Min(arr[0], arr[1:]...)
  1325. //
  1326. // This makes it harder to accidentally call Min with 0 arguments.
  1327. func Min(first Decimal, rest ...Decimal) Decimal {
  1328. ans := first
  1329. for _, item := range rest {
  1330. if item.Cmp(ans) < 0 {
  1331. ans = item
  1332. }
  1333. }
  1334. return ans
  1335. }
  1336. // Max returns the largest Decimal that was passed in the arguments.
  1337. //
  1338. // To call this function with an array, you must do:
  1339. //
  1340. // Max(arr[0], arr[1:]...)
  1341. //
  1342. // This makes it harder to accidentally call Max with 0 arguments.
  1343. func Max(first Decimal, rest ...Decimal) Decimal {
  1344. ans := first
  1345. for _, item := range rest {
  1346. if item.Cmp(ans) > 0 {
  1347. ans = item
  1348. }
  1349. }
  1350. return ans
  1351. }
  1352. // Sum returns the combined total of the provided first and rest Decimals
  1353. func Sum(first Decimal, rest ...Decimal) Decimal {
  1354. total := first
  1355. for _, item := range rest {
  1356. total = total.Add(item)
  1357. }
  1358. return total
  1359. }
  1360. // Avg returns the average value of the provided first and rest Decimals
  1361. func Avg(first Decimal, rest ...Decimal) Decimal {
  1362. count := New(int64(len(rest)+1), 0)
  1363. sum := Sum(first, rest...)
  1364. return sum.Div(count)
  1365. }
  1366. // RescalePair rescales two decimals to common exponential value (minimal exp of both decimals)
  1367. func RescalePair(d1 Decimal, d2 Decimal) (Decimal, Decimal) {
  1368. d1.ensureInitialized()
  1369. d2.ensureInitialized()
  1370. if d1.exp == d2.exp {
  1371. return d1, d2
  1372. }
  1373. baseScale := min(d1.exp, d2.exp)
  1374. if baseScale != d1.exp {
  1375. return d1.rescale(baseScale), d2
  1376. }
  1377. return d1, d2.rescale(baseScale)
  1378. }
  1379. func min(x, y int32) int32 {
  1380. if x >= y {
  1381. return y
  1382. }
  1383. return x
  1384. }
  1385. func unquoteIfQuoted(value interface{}) (string, error) {
  1386. var bytes []byte
  1387. switch v := value.(type) {
  1388. case string:
  1389. bytes = []byte(v)
  1390. case []byte:
  1391. bytes = v
  1392. default:
  1393. return "", fmt.Errorf("could not convert value '%+v' to byte array of type '%T'",
  1394. value, value)
  1395. }
  1396. // If the amount is quoted, strip the quotes
  1397. if len(bytes) > 2 && bytes[0] == '"' && bytes[len(bytes)-1] == '"' {
  1398. bytes = bytes[1 : len(bytes)-1]
  1399. }
  1400. return string(bytes), nil
  1401. }
  1402. // NullDecimal represents a nullable decimal with compatibility for
  1403. // scanning null values from the database.
  1404. type NullDecimal struct {
  1405. Decimal Decimal
  1406. Valid bool
  1407. }
  1408. func NewNullDecimal(d Decimal) NullDecimal {
  1409. return NullDecimal{
  1410. Decimal: d,
  1411. Valid: true,
  1412. }
  1413. }
  1414. // Scan implements the sql.Scanner interface for database deserialization.
  1415. func (d *NullDecimal) Scan(value interface{}) error {
  1416. if value == nil {
  1417. d.Valid = false
  1418. return nil
  1419. }
  1420. d.Valid = true
  1421. return d.Decimal.Scan(value)
  1422. }
  1423. // Value implements the driver.Valuer interface for database serialization.
  1424. func (d NullDecimal) Value() (driver.Value, error) {
  1425. if !d.Valid {
  1426. return nil, nil
  1427. }
  1428. return d.Decimal.Value()
  1429. }
  1430. // UnmarshalJSON implements the json.Unmarshaler interface.
  1431. func (d *NullDecimal) UnmarshalJSON(decimalBytes []byte) error {
  1432. if string(decimalBytes) == "null" {
  1433. d.Valid = false
  1434. return nil
  1435. }
  1436. d.Valid = true
  1437. return d.Decimal.UnmarshalJSON(decimalBytes)
  1438. }
  1439. // MarshalJSON implements the json.Marshaler interface.
  1440. func (d NullDecimal) MarshalJSON() ([]byte, error) {
  1441. if !d.Valid {
  1442. return []byte("null"), nil
  1443. }
  1444. return d.Decimal.MarshalJSON()
  1445. }
  1446. // UnmarshalText implements the encoding.TextUnmarshaler interface for XML
  1447. // deserialization
  1448. func (d *NullDecimal) UnmarshalText(text []byte) error {
  1449. str := string(text)
  1450. // check for empty XML or XML without body e.g., <tag></tag>
  1451. if str == "" {
  1452. d.Valid = false
  1453. return nil
  1454. }
  1455. if err := d.Decimal.UnmarshalText(text); err != nil {
  1456. d.Valid = false
  1457. return err
  1458. }
  1459. d.Valid = true
  1460. return nil
  1461. }
  1462. // MarshalText implements the encoding.TextMarshaler interface for XML
  1463. // serialization.
  1464. func (d NullDecimal) MarshalText() (text []byte, err error) {
  1465. if !d.Valid {
  1466. return []byte{}, nil
  1467. }
  1468. return d.Decimal.MarshalText()
  1469. }
  1470. // Trig functions
  1471. // Atan returns the arctangent, in radians, of x.
  1472. func (d Decimal) Atan() Decimal {
  1473. if d.Equal(NewFromFloat(0.0)) {
  1474. return d
  1475. }
  1476. if d.GreaterThan(NewFromFloat(0.0)) {
  1477. return d.satan()
  1478. }
  1479. return d.Neg().satan().Neg()
  1480. }
  1481. func (d Decimal) xatan() Decimal {
  1482. P0 := NewFromFloat(-8.750608600031904122785e-01)
  1483. P1 := NewFromFloat(-1.615753718733365076637e+01)
  1484. P2 := NewFromFloat(-7.500855792314704667340e+01)
  1485. P3 := NewFromFloat(-1.228866684490136173410e+02)
  1486. P4 := NewFromFloat(-6.485021904942025371773e+01)
  1487. Q0 := NewFromFloat(2.485846490142306297962e+01)
  1488. Q1 := NewFromFloat(1.650270098316988542046e+02)
  1489. Q2 := NewFromFloat(4.328810604912902668951e+02)
  1490. Q3 := NewFromFloat(4.853903996359136964868e+02)
  1491. Q4 := NewFromFloat(1.945506571482613964425e+02)
  1492. z := d.Mul(d)
  1493. b1 := P0.Mul(z).Add(P1).Mul(z).Add(P2).Mul(z).Add(P3).Mul(z).Add(P4).Mul(z)
  1494. b2 := z.Add(Q0).Mul(z).Add(Q1).Mul(z).Add(Q2).Mul(z).Add(Q3).Mul(z).Add(Q4)
  1495. z = b1.Div(b2)
  1496. z = d.Mul(z).Add(d)
  1497. return z
  1498. }
  1499. // satan reduces its argument (known to be positive)
  1500. // to the range [0, 0.66] and calls xatan.
  1501. func (d Decimal) satan() Decimal {
  1502. Morebits := NewFromFloat(6.123233995736765886130e-17) // pi/2 = PIO2 + Morebits
  1503. Tan3pio8 := NewFromFloat(2.41421356237309504880) // tan(3*pi/8)
  1504. pi := NewFromFloat(3.14159265358979323846264338327950288419716939937510582097494459)
  1505. if d.LessThanOrEqual(NewFromFloat(0.66)) {
  1506. return d.xatan()
  1507. }
  1508. if d.GreaterThan(Tan3pio8) {
  1509. return pi.Div(NewFromFloat(2.0)).Sub(NewFromFloat(1.0).Div(d).xatan()).Add(Morebits)
  1510. }
  1511. return pi.Div(NewFromFloat(4.0)).Add((d.Sub(NewFromFloat(1.0)).Div(d.Add(NewFromFloat(1.0)))).xatan()).Add(NewFromFloat(0.5).Mul(Morebits))
  1512. }
  1513. // sin coefficients
  1514. var _sin = [...]Decimal{
  1515. NewFromFloat(1.58962301576546568060e-10), // 0x3de5d8fd1fd19ccd
  1516. NewFromFloat(-2.50507477628578072866e-8), // 0xbe5ae5e5a9291f5d
  1517. NewFromFloat(2.75573136213857245213e-6), // 0x3ec71de3567d48a1
  1518. NewFromFloat(-1.98412698295895385996e-4), // 0xbf2a01a019bfdf03
  1519. NewFromFloat(8.33333333332211858878e-3), // 0x3f8111111110f7d0
  1520. NewFromFloat(-1.66666666666666307295e-1), // 0xbfc5555555555548
  1521. }
  1522. // Sin returns the sine of the radian argument x.
  1523. func (d Decimal) Sin() Decimal {
  1524. PI4A := NewFromFloat(7.85398125648498535156e-1) // 0x3fe921fb40000000, Pi/4 split into three parts
  1525. PI4B := NewFromFloat(3.77489470793079817668e-8) // 0x3e64442d00000000,
  1526. PI4C := NewFromFloat(2.69515142907905952645e-15) // 0x3ce8469898cc5170,
  1527. M4PI := NewFromFloat(1.273239544735162542821171882678754627704620361328125) // 4/pi
  1528. if d.Equal(NewFromFloat(0.0)) {
  1529. return d
  1530. }
  1531. // make argument positive but save the sign
  1532. sign := false
  1533. if d.LessThan(NewFromFloat(0.0)) {
  1534. d = d.Neg()
  1535. sign = true
  1536. }
  1537. j := d.Mul(M4PI).IntPart() // integer part of x/(Pi/4), as integer for tests on the phase angle
  1538. y := NewFromFloat(float64(j)) // integer part of x/(Pi/4), as float
  1539. // map zeros to origin
  1540. if j&1 == 1 {
  1541. j++
  1542. y = y.Add(NewFromFloat(1.0))
  1543. }
  1544. j &= 7 // octant modulo 2Pi radians (360 degrees)
  1545. // reflect in x axis
  1546. if j > 3 {
  1547. sign = !sign
  1548. j -= 4
  1549. }
  1550. z := d.Sub(y.Mul(PI4A)).Sub(y.Mul(PI4B)).Sub(y.Mul(PI4C)) // Extended precision modular arithmetic
  1551. zz := z.Mul(z)
  1552. if j == 1 || j == 2 {
  1553. w := zz.Mul(zz).Mul(_cos[0].Mul(zz).Add(_cos[1]).Mul(zz).Add(_cos[2]).Mul(zz).Add(_cos[3]).Mul(zz).Add(_cos[4]).Mul(zz).Add(_cos[5]))
  1554. y = NewFromFloat(1.0).Sub(NewFromFloat(0.5).Mul(zz)).Add(w)
  1555. } else {
  1556. y = z.Add(z.Mul(zz).Mul(_sin[0].Mul(zz).Add(_sin[1]).Mul(zz).Add(_sin[2]).Mul(zz).Add(_sin[3]).Mul(zz).Add(_sin[4]).Mul(zz).Add(_sin[5])))
  1557. }
  1558. if sign {
  1559. y = y.Neg()
  1560. }
  1561. return y
  1562. }
  1563. // cos coefficients
  1564. var _cos = [...]Decimal{
  1565. NewFromFloat(-1.13585365213876817300e-11), // 0xbda8fa49a0861a9b
  1566. NewFromFloat(2.08757008419747316778e-9), // 0x3e21ee9d7b4e3f05
  1567. NewFromFloat(-2.75573141792967388112e-7), // 0xbe927e4f7eac4bc6
  1568. NewFromFloat(2.48015872888517045348e-5), // 0x3efa01a019c844f5
  1569. NewFromFloat(-1.38888888888730564116e-3), // 0xbf56c16c16c14f91
  1570. NewFromFloat(4.16666666666665929218e-2), // 0x3fa555555555554b
  1571. }
  1572. // Cos returns the cosine of the radian argument x.
  1573. func (d Decimal) Cos() Decimal {
  1574. PI4A := NewFromFloat(7.85398125648498535156e-1) // 0x3fe921fb40000000, Pi/4 split into three parts
  1575. PI4B := NewFromFloat(3.77489470793079817668e-8) // 0x3e64442d00000000,
  1576. PI4C := NewFromFloat(2.69515142907905952645e-15) // 0x3ce8469898cc5170,
  1577. M4PI := NewFromFloat(1.273239544735162542821171882678754627704620361328125) // 4/pi
  1578. // make argument positive
  1579. sign := false
  1580. if d.LessThan(NewFromFloat(0.0)) {
  1581. d = d.Neg()
  1582. }
  1583. j := d.Mul(M4PI).IntPart() // integer part of x/(Pi/4), as integer for tests on the phase angle
  1584. y := NewFromFloat(float64(j)) // integer part of x/(Pi/4), as float
  1585. // map zeros to origin
  1586. if j&1 == 1 {
  1587. j++
  1588. y = y.Add(NewFromFloat(1.0))
  1589. }
  1590. j &= 7 // octant modulo 2Pi radians (360 degrees)
  1591. // reflect in x axis
  1592. if j > 3 {
  1593. sign = !sign
  1594. j -= 4
  1595. }
  1596. if j > 1 {
  1597. sign = !sign
  1598. }
  1599. z := d.Sub(y.Mul(PI4A)).Sub(y.Mul(PI4B)).Sub(y.Mul(PI4C)) // Extended precision modular arithmetic
  1600. zz := z.Mul(z)
  1601. if j == 1 || j == 2 {
  1602. y = z.Add(z.Mul(zz).Mul(_sin[0].Mul(zz).Add(_sin[1]).Mul(zz).Add(_sin[2]).Mul(zz).Add(_sin[3]).Mul(zz).Add(_sin[4]).Mul(zz).Add(_sin[5])))
  1603. } else {
  1604. w := zz.Mul(zz).Mul(_cos[0].Mul(zz).Add(_cos[1]).Mul(zz).Add(_cos[2]).Mul(zz).Add(_cos[3]).Mul(zz).Add(_cos[4]).Mul(zz).Add(_cos[5]))
  1605. y = NewFromFloat(1.0).Sub(NewFromFloat(0.5).Mul(zz)).Add(w)
  1606. }
  1607. if sign {
  1608. y = y.Neg()
  1609. }
  1610. return y
  1611. }
  1612. var _tanP = [...]Decimal{
  1613. NewFromFloat(-1.30936939181383777646e+4), // 0xc0c992d8d24f3f38
  1614. NewFromFloat(1.15351664838587416140e+6), // 0x413199eca5fc9ddd
  1615. NewFromFloat(-1.79565251976484877988e+7), // 0xc1711fead3299176
  1616. }
  1617. var _tanQ = [...]Decimal{
  1618. NewFromFloat(1.00000000000000000000e+0),
  1619. NewFromFloat(1.36812963470692954678e+4), //0x40cab8a5eeb36572
  1620. NewFromFloat(-1.32089234440210967447e+6), //0xc13427bc582abc96
  1621. NewFromFloat(2.50083801823357915839e+7), //0x4177d98fc2ead8ef
  1622. NewFromFloat(-5.38695755929454629881e+7), //0xc189afe03cbe5a31
  1623. }
  1624. // Tan returns the tangent of the radian argument x.
  1625. func (d Decimal) Tan() Decimal {
  1626. PI4A := NewFromFloat(7.85398125648498535156e-1) // 0x3fe921fb40000000, Pi/4 split into three parts
  1627. PI4B := NewFromFloat(3.77489470793079817668e-8) // 0x3e64442d00000000,
  1628. PI4C := NewFromFloat(2.69515142907905952645e-15) // 0x3ce8469898cc5170,
  1629. M4PI := NewFromFloat(1.273239544735162542821171882678754627704620361328125) // 4/pi
  1630. if d.Equal(NewFromFloat(0.0)) {
  1631. return d
  1632. }
  1633. // make argument positive but save the sign
  1634. sign := false
  1635. if d.LessThan(NewFromFloat(0.0)) {
  1636. d = d.Neg()
  1637. sign = true
  1638. }
  1639. j := d.Mul(M4PI).IntPart() // integer part of x/(Pi/4), as integer for tests on the phase angle
  1640. y := NewFromFloat(float64(j)) // integer part of x/(Pi/4), as float
  1641. // map zeros to origin
  1642. if j&1 == 1 {
  1643. j++
  1644. y = y.Add(NewFromFloat(1.0))
  1645. }
  1646. z := d.Sub(y.Mul(PI4A)).Sub(y.Mul(PI4B)).Sub(y.Mul(PI4C)) // Extended precision modular arithmetic
  1647. zz := z.Mul(z)
  1648. if zz.GreaterThan(NewFromFloat(1e-14)) {
  1649. w := zz.Mul(_tanP[0].Mul(zz).Add(_tanP[1]).Mul(zz).Add(_tanP[2]))
  1650. x := zz.Add(_tanQ[1]).Mul(zz).Add(_tanQ[2]).Mul(zz).Add(_tanQ[3]).Mul(zz).Add(_tanQ[4])
  1651. y = z.Add(z.Mul(w.Div(x)))
  1652. } else {
  1653. y = z
  1654. }
  1655. if j&2 == 2 {
  1656. y = NewFromFloat(-1.0).Div(y)
  1657. }
  1658. if sign {
  1659. y = y.Neg()
  1660. }
  1661. return y
  1662. }