Reputation: 31
how to get the log with base 16 for a math/big Int variable.
Any help would be great since I am new to Go and came from Python and C environment
s := "c6d86e5a2cb4bc532361c2d4940f0b1a0138066e25d65c1c530d080b11f8ca24" // Hex value
i := new(big.Int)
i.SetString(s, 16) // hex value to Big Int
// how to get the log with base 16 for a math/big Int variable.
How it works in python
import math
a = 0xc6d86e5a2cb4bc532361c2d4940f0b1a0138066e25d65c1c530d080b11f8ca24
a>> 89940344608680314083397671686667731393131665861770496634981932531495305005604L
math.log(a)/math.log(16.0)
answer turns out to be 63.908875905794794
Upvotes: 1
Views: 2966
Reputation: 80257
There is specific approach for log16 and hex input without long arithmetics.
To get integer (floored) result, just count hex digits. In this case there are 63 digits, so you have
FloorLog16 = 63
Now get 8 first digits (more to enhance precision)
b = 0xc6d86e5a
and get log16
p = log(b) / log(16) = 7.908875905775919
Use fractional part of this result to make logarithm more exact
fp = p - Floor(p) = 0.908875905775919
log16(0xc6d86e5a2cb4bc532361c2d4940f0b1a0138066e25d65c1c530d080b11f8ca24) =
63 + 0.908875905775919 = 63.908875905775919
Note 12 exact digits
Upvotes: 5
Reputation: 2970
An interesting property of logarithms is that change-of-base is actually pretty easy.
log_b (x) = log_a (x) / log_a (b)
So if you want to get log_16 (x)
, you could use the Log function and do change of base:
log_e (x) = log_16 (x) / log_16 (e)
log_16 (e) = approximately 0.36067
=> log_16 (x) = 0.36067 * log_e (x)
So in Go, I think this would be:
li := Log(i) * 0.36067
Edit: When I wrote the answer above I did not realize that Log
wouldn't work on a Big Int. Reading the Go Github, it looks like this is a requested feature in the language which has not yet been implemented due to lack of a satisfactorily quick solution. From what I read it looks like the best solution for the moment, if you must use a Big Int, is probably a Taylor Series implementation, which in my opinion would be non-trivial to write. The thread I linked to indicates that one or more such implementations may exist but are not necessarily computationally correct.
Upvotes: 6
Reputation: 957
First you need to convert the hex string to the correct hex notation by adding "0x" at the beginning. Next write a log16
method, use strconv
to get the integer, than float64
for the input of the log
method. Caution: this solution does not deal with integer overflow.
package main
import (
"fmt"
"math"
"strconv"
)
func log16(x float64) float64 {
return math.Log(x)/math.Log(16.0)
}
func main() {
s := "c6d86e5a2cb4bc532361c2d4940f0b1a0138066e25d65c1c530d080b11f8ca24"
s1 := "0x" + s
h, _ := strconv.ParseInt(s1,0,64)
fmt.Println(log16(float64(h)))
}
Upvotes: 1