Ceiling Func prior to go1.10 - go

I require a custom 'Ceil' func that works like in go1.10 upwards as we are on v1.9 (obv wont be as performant but thats ok)
e.g
Ceil(0.33) = 1.00
I have seen some general nearest int roundings solutions, however, wondering if anyone has implemented an equiv 'Ceil' func for v1.9 as a work around?

Since Go is open source, you can just use their code directly: https://golang.org/src/math/floor.go?s=720:748#L26
I have looked into the code and extracted all the bits and pieces into this little program for you:
package main
import (
"fmt"
"unsafe"
)
func main() {
fmt.Println(ceil(1.5))
fmt.Println(ceil(0.5))
fmt.Println(ceil(0.0))
fmt.Println(ceil(-0.5))
fmt.Println(ceil(-1.5))
}
func ceil(x float64) float64 {
return -floor(-x)
}
func floor(x float64) float64 {
if x == 0 || isNaN(x) || isInf(x, 0) {
return x
}
if x < 0 {
d, fract := modf(-x)
if fract != 0.0 {
d = d + 1
}
return -d
}
d, _ := modf(x)
return d
}
func isNaN(f float64) (is bool) {
return f != f
}
func isInf(f float64, sign int) bool {
return sign >= 0 && f > maxFloat64 || sign <= 0 && f < -maxFloat64
}
func modf(f float64) (int float64, frac float64) {
if f < 1 {
switch {
case f < 0:
int, frac = modf(-f)
return -int, -frac
case f == 0:
return f, f
}
return 0, f
}
x := float64bits(f)
e := uint(x>>shift)&mask - bias
if e < 64-12 {
x &^= 1<<(64-12-e) - 1
}
int = float64frombits(x)
frac = f - int
return
}
const (
maxFloat64 = 1.797693134862315708145274237317043567981e+308
mask = 0x7FF
shift = 64 - 11 - 1
bias = 1023
)
func float64bits(f float64) uint64 {
return *(*uint64)(unsafe.Pointer(&f))
}
func float64frombits(b uint64) float64 {
return *(*float64)(unsafe.Pointer(&b))
}

Related

golang convert big.Float to big.Int

convert big.Float to big.Int, i write code below, but it overflow with uint64, so what's the correct way to cenvert big.Float to big.Int.
package main
import "fmt"
import "math/big"
func FloatToBigInt(val float64) *big.Int {
bigval := new(big.Float)
bigval.SetFloat64(val)
coin := new(big.Float)
coin.SetInt(big.NewInt(1000000000000000000))
bigval.Mul(bigval, coin)
result := new(big.Int)
f,_ := bigval.Uint64()
result.SetUint64(f)
return result
}
func main() {
fmt.Println("vim-go")
fmt.Println(FloatToBigInt(float64(10)))
fmt.Println(FloatToBigInt(float64(20)))
fmt.Println(FloatToBigInt(float64(30)))
fmt.Println(FloatToBigInt(float64(40)))
fmt.Println(FloatToBigInt(float64(50)))
fmt.Println(FloatToBigInt(float64(100)))
fmt.Println(FloatToBigInt(float64(1000)))
fmt.Println(FloatToBigInt(float64(10000)))
}
A big int bigger than uint64 will always cause an overflow as uint64 has fixed size. You should use the following method on *Float:
func (*Float) Int
The changes required would be:
func FloatToBigInt(val float64) *big.Int {
bigval := new(big.Float)
bigval.SetFloat64(val)
// Set precision if required.
// bigval.SetPrec(64)
coin := new(big.Float)
coin.SetInt(big.NewInt(1000000000000000000))
bigval.Mul(bigval, coin)
result := new(big.Int)
bigval.Int(result) // store converted number in result
return result
}
Working example: https://play.golang.org/p/sEhH6iPkrK
Use the function Float.Int(nil)
I have worked with a regular float64 number (not big.Float) and found out that conversion via string is the most precise way. Check it out
Note: the example is for float64 -> decimal(,20) conversion.
func bigIntViaString(flt float64) (b *big.Int) {
if math.IsNaN(flt) || math.IsInf(flt, 0) {
return nil // illegal case
}
var in = strconv.FormatFloat(flt, 'f', -1, 64)
const parts = 2
var ss = strings.SplitN(in, ".", parts)
// protect from numbers without period
if len(ss) != parts {
ss = append(ss, "0")
}
// protect from ".0" and "0." values
if ss[0] == "" {
ss[0] = "0"
}
if ss[1] == "" {
ss[1] = "0"
}
const (
base = 10
fraction = 20
)
// get fraction length
var fract = len(ss[1])
if fract > fraction {
ss[1], fract = ss[1][:fraction], fraction
}
in = strings.Join([]string{ss[0], ss[1]}, "")
// convert to big integer from the string
b, _ = big.NewInt(0).SetString(in, base)
if fract == fraction {
return // ready
}
// fract < 20, * (20 - fract)
var (
ten = big.NewInt(base)
exp = ten.Exp(ten, big.NewInt(fraction-int64(fract)), nil)
)
b = b.Mul(b, exp)
return
}
https://play.golang.org/p/_lkyQ_0udjd

Lychrel Numbers in Go with the big Library

I'm trying to make a Lychrel number program in Go, but I'm running into some trouble. Using the "math/big" library, and with some extra print statements for debugging, my code looks like this:
func reverse(n *big.Int) *big.Int {
var (
m = n
r = big.NewInt(0)
z = big.NewInt(0)
one = big.NewInt(1)
ten = big.NewInt(10)
)
for {
r.Mul(r, ten)
d := z
d.Mod(m, ten)
r.Add(r, d)
m.Div(m, ten)
if m.Cmp(one) == -1 {
return r
}
}
}
func radd(num *big.Int) *big.Int {
newNum := num
rnum := reverse(num)
newNum = newNum.Add(num, rnum)
fmt.Println(num, "+", rnum, "=", newNum)
return newNum
}
func lychrel(arg int) bool {
fmt.Println("Now testing", arg)
num := big.NewInt(int64(arg))
for i := 0; i < 50; i++ {
num = radd(num)
fmt.Println(i, ":", num)
if num.Cmp(reverse(num)) == 0 {
return false
}
}
return true
}
While the analogous code without the big library works fine (save for eventual overflow errors), this version doesn't. When I do lychrel(196), for example, I get
Now testing 196
691 + 691 = 691
0 : 691
0 + 0 = 0
1 : 0
I can't figure out where it goes wrong. I hope I'm not missing something dumb, because I've spent all morning trying to get this to work.
Package big
import "math/big"
func NewInt
func NewInt(x int64) *Int
NewInt allocates and returns a new Int set to x.
func (*Int) Set
func (z *Int) Set(x *Int) *Int
Set sets z to x and returns z.
You are assigning pointers, instead of values.
m = n
newNum := num
Assign values,
m = new(big.Int).Set(n)
newNum := new(big.Int).Set(num)
For example,
package main
import (
"fmt"
"math/big"
)
func reverse(n *big.Int) *big.Int {
var (
m = new(big.Int).Set(n)
r = big.NewInt(0)
z = big.NewInt(0)
one = big.NewInt(1)
ten = big.NewInt(10)
)
for {
r.Mul(r, ten)
d := z
d.Mod(m, ten)
r.Add(r, d)
m.Div(m, ten)
if m.Cmp(one) == -1 {
return r
}
}
}
func radd(num *big.Int) *big.Int {
newNum := new(big.Int).Set(num)
rnum := reverse(num)
newNum = newNum.Add(num, rnum)
fmt.Println(num, "+", rnum, "=", newNum)
return newNum
}
func lychrel(arg int) bool {
fmt.Println("Now testing", arg)
num := big.NewInt(int64(arg))
for i := 0; i < 50; i++ {
num = radd(num)
fmt.Println(i, ":", num)
if num.Cmp(reverse(num)) == 0 {
return false
}
}
return true
}
func main() {
lychrel(196)
}
Output:
Now testing 196
196 + 691 = 887
0 : 887
. . .

Condition validation in for loop

my below code to get square root works fine
package main
import (
"fmt"
"math"
)
func main() {
fmt.Println(Sqrt(9))
}
func Sqrt(x float64) float64 {
v := float64(1)
p := float64(0)
for {
p = v
v -= (v*v - x) / (2 * v)
fmt.Println(toFixed(p, 5), toFixed(v, 5))
if toFixed(p, 5) == toFixed(v, 5) {
break
}
}
return v
}
func toFixed(num float64, precision int) float64 {
output := math.Pow(10, float64(precision))
return float64(round(num*output)) / output
}
func round(num float64) int {
return int(num + math.Copysign(0.5, num))
}
but if I change the for loop in Sqrt function and remove if break from the loop like below then control flow do not get into for loop and Sqrt() function quits with value as 1.
for toFixed(p, 5) == toFixed(v, 5) {
p = v
v -= (v*v - x) / (2 * v)
fmt.Println(toFixed(p, 5), toFixed(v, 5))
}
Can you please suggest issue in above code?
Thanks
You should be checking for inequality != in your for condition.
I modified your code and it seems to be working fine now:
package main
import (
"fmt"
"math"
)
func main() {
fmt.Println(Sqrt(9))
}
func Sqrt(x float64) float64 {
v := float64(1)
p := float64(0)
for toFixed(p, 5) != toFixed(v, 5) {
p = v
v -= (v*v - x) / (2 * v)
}
return v
}
func toFixed(num float64, precision int) float64 {
output := math.Pow(10, float64(precision))
return float64(round(num*output)) / output
}
func round(num float64) int {
return int(num + math.Copysign(0.5, num))
}

How to convert int to bigint in golang?

I'm trying to implement fast double Fibonacci algorithm as described here:
// Fast doubling Fibonacci algorithm
package main
import "fmt"
// (Public) Returns F(n).
func fibonacci(n int) int {
if n < 0 {
panic("Negative arguments not implemented")
}
fst, _ := fib(n)
return fst
}
// (Private) Returns the tuple (F(n), F(n+1)).
func fib(n int) (int, int) {
if n == 0 {
return 0, 1
}
a, b := fib(n / 2)
c := a * (b*2 - a)
d := a*a + b*b
if n%2 == 0 {
return c, d
} else {
return d, c + d
}
}
func main() {
fmt.Println(fibonacci(13))
fmt.Println(fibonacci(14))
}
This works fine for small numbers; however, when the input number get larger, the program returns a wrong result. So I tried to use bigInt from math/big package:
// Fast doubling Fibonacci algorithm
package main
import (
"fmt"
"math/big"
)
// (Public) Returns F(n).
func fibonacci(n int) big.Int {
if n < 0 {
panic("Negative arguments not implemented")
}
fst, _ := fib(n)
return fst
}
// (Private) Returns the tuple (F(n), F(n+1)).
func fib(n int) (big.Int, big.Int) {
if n == 0 {
return big.Int(0), big.Int(1)
}
a, b := fib(n / 2)
c := a * (b*2 - a)
d := a*a + b*b
if n%2 == 0 {
return c, d
} else {
return d, c + d
}
}
func main() {
fmt.Println(fibonacci(123))
fmt.Println(fibonacci(124))
}
However, go build complains that
cannot convert 0 (type int) to type big.Int
How to mitigate this problem?
Use big.NewInt() instead of big.Int(). big.Int() is just type casting.
You need to check out documentation of big package
You should mostly use methods with form func (z *T) Binary(x, y *T) *T // z = x op y
To multiply 2 arguments you need to provide result variable, after it call Mul method. So, for example, to get result of 2*2 you need to:
big.NewInt(0).Mul(big.NewInt(2), big.NewInt(2))
You can try working example on the Go playground
Also you can create extension functions like:
func Mul(x, y *big.Int) *big.Int {
return big.NewInt(0).Mul(x, y)
}
To make code more readable:
// Fast doubling Fibonacci algorithm
package main
import (
"fmt"
"math/big"
)
// (Public) Returns F(n).
func fibonacci(n int) *big.Int {
if n < 0 {
panic("Negative arguments not implemented")
}
fst, _ := fib(n)
return fst
}
// (Private) Returns the tuple (F(n), F(n+1)).
func fib(n int) (*big.Int, *big.Int) {
if n == 0 {
return big.NewInt(0), big.NewInt(1)
}
a, b := fib(n / 2)
c := Mul(a, Sub(Mul(b, big.NewInt(2)), a))
d := Add(Mul(a, a), Mul(b, b))
if n%2 == 0 {
return c, d
} else {
return d, Add(c, d)
}
}
func main() {
fmt.Println(fibonacci(123))
fmt.Println(fibonacci(124))
}
func Mul(x, y *big.Int) *big.Int {
return big.NewInt(0).Mul(x, y)
}
func Sub(x, y *big.Int) *big.Int {
return big.NewInt(0).Sub(x, y)
}
func Add(x, y *big.Int) *big.Int {
return big.NewInt(0).Add(x, y)
}
Try it on the Go playground

Go big.Int factorial with recursion

I am trying to implement this bit of code:
func factorial(x int) (result int) {
if x == 0 {
result = 1;
} else {
result = x * factorial(x - 1);
}
return;
}
as a big.Int so as to make it effective for larger values of x.
The following is returning a value of 0 for fmt.Println(factorial(r))
The factorial of 7 should be 5040?
Any ideas on what I am doing wrong?
package main
import "fmt"
import "math/big"
func main() {
fmt.Println("Hello, playground")
//n := big.NewInt(40)
r := big.NewInt(7)
fmt.Println(factorial(r))
}
func factorial(n *big.Int) (result *big.Int) {
//fmt.Println("n = ", n)
b := big.NewInt(0)
c := big.NewInt(1)
if n.Cmp(b) == -1 {
result = big.NewInt(1)
}
if n.Cmp(b) == 0 {
result = big.NewInt(1)
} else {
// return n * factorial(n - 1);
fmt.Println("n = ", n)
result = n.Mul(n, factorial(n.Sub(n, c)))
}
return result
}
This code on go playground: http://play.golang.org/p/yNlioSdxi4
Go package math.big has func (*Int) MulRange(a, b int64). When called with the first parameter set to 1, it will return b!:
package main
import (
"fmt"
"math/big"
)
func main() {
x := new(big.Int)
x.MulRange(1, 10)
fmt.Println(x)
}
Will produce
3628800
In your int version, every int is distinct. But in your big.Int version, you're actually sharing big.Int values. So when you say
result = n.Mul(n, factorial(n.Sub(n, c)))
The expression n.Sub(n, c) actually stores 0 back into n, so when n.Mul(n, ...) is evaluated, you're basically doing 0 * 1 and you get back 0 as a result.
Remember, the results of big.Int operations don't just return their value, they also store them into the receiver. This is why you see repetition in expressions like n.Mul(n, c), e.g. why it takes n again as the first parameter. Because you could also sayresult.Mul(n, c) and you'd get the same value back, but it would be stored in result instead of n.
Here is your code rewritten to avoid this problem:
func factorial(n *big.Int) (result *big.Int) {
//fmt.Println("n = ", n)
b := big.NewInt(0)
c := big.NewInt(1)
if n.Cmp(b) == -1 {
result = big.NewInt(1)
}
if n.Cmp(b) == 0 {
result = big.NewInt(1)
} else {
// return n * factorial(n - 1);
fmt.Println("n = ", n)
result = new(big.Int)
result.Set(n)
result.Mul(result, factorial(n.Sub(n, c)))
}
return
}
And here is a slightly more cleaned-up/optimized version (I tried to remove extraneous allocations of big.Ints): http://play.golang.org/p/feacvk4P4O
For example,
package main
import (
"fmt"
"math/big"
)
func factorial(x *big.Int) *big.Int {
n := big.NewInt(1)
if x.Cmp(big.NewInt(0)) == 0 {
return n
}
return n.Mul(x, factorial(n.Sub(x, n)))
}
func main() {
r := big.NewInt(7)
fmt.Println(factorial(r))
}
Output:
5040
Non-recursive version:
func FactorialBig(n uint64) (r *big.Int) {
//fmt.Println("n = ", n)
one, bn := big.NewInt(1), new(big.Int).SetUint64(n)
r = big.NewInt(1)
if bn.Cmp(one) <= 0 {
return
}
for i := big.NewInt(2); i.Cmp(bn) <= 0; i.Add(i, one) {
r.Mul(r, i)
}
return
}
playground

Resources