-
Notifications
You must be signed in to change notification settings - Fork 1
/
number.go
137 lines (117 loc) · 3.65 KB
/
number.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
// Package number provide a common representation of integers and floating point
// numbers uting big.Int's. It transform any number into its integer based
// standard form representation, storing its integer value and the correct
// exponent to keep the original value:
//
// X = value * 10^exp --> 1.032 = 1032 * 10^-3
//
// This package allows to use any integer based cryptosystem over floating point
// numbers too.
package number
import "math/big"
var iZero = big.NewInt(0)
var iOne = big.NewInt(1)
var iTen = big.NewInt(10)
var fZero = big.NewFloat(0)
var fTen = big.NewFloat(10)
// Struct Number includes the integers value of the original number with the
// original power of ten exponent, allowing to encrypt and decrypt the value and
// operate over it.
type Number struct {
Value *big.Int
Exp *big.Int
encrypted bool
}
// Function IsEncrypted return if the current number representation is encrypted
// or not.
func (num *Number) IsEncrypted() bool {
return num.encrypted
}
// Function Set copy the values of the original Number into the current Number
// num and return it as result. By default, the resulting Number will be
// created as decrypted, to create as encrypted use number.SetEncrypted()
// function.
func (num *Number) Set(original *Number) *Number {
num.Value = original.Value
num.Exp = original.Exp
num.encrypted = false
return num
}
// Function SetEncrypted copy the values of the original Number into the current
// Number num and return it as result. By default, the resulting Number will be
// created as encrypted, to create as decrypted use number.Set() function.
func (num *Number) SetEncrypted(original *Number) *Number {
num.Set(original)
num.encrypted = true
return num
}
// Function SetInt compute and stores into the current Number num the correct
// integer value and exponent of the provided int input and return it as result.
func (num *Number) SetInt(input int64) *Number {
if input == 0 {
num.Value = iZero
num.Exp = iOne
return num
}
var bInput = big.NewInt(input)
var exp int64
for new(big.Int).Mod(bInput, iTen).Cmp(iZero) == 0 {
bInput.Div(bInput, iTen)
exp++
}
num.Value = new(big.Int).Set(bInput)
num.Exp = big.NewInt(exp)
return num
}
// Function SetFloat compute and stores into the current Number num the correct
// integer value and exponent of the provided float input and return it as
// result.
func (num *Number) SetFloat(input float64) *Number {
var bInput = big.NewFloat(input)
var value, exp int64 = int64(input), 0
var diff = new(big.Float).Sub(bInput, big.NewFloat(float64(value)))
for diff.Cmp(fZero) != 0 {
bInput = new(big.Float).Mul(bInput, fTen)
value, _ = bInput.Int64()
exp--
diff = new(big.Float).Sub(bInput, big.NewFloat(float64(value)))
}
var numInt = new(Number).SetInt(value)
num.Value = numInt.Value
num.Exp = new(big.Int).Add(numInt.Exp, big.NewInt(exp))
return num
}
// Function Int returns the original int value of the current Number num
// computing the value of num.Value * 10^num.Exp.
func (num *Number) Int() (output int64) {
var bOutput = new(big.Int).Set(num.Value)
var exp = num.Exp.Int64()
for exp != 0 {
if exp > 0 {
bOutput.Mul(bOutput, iTen)
exp--
} else {
bOutput.Div(bOutput, iTen)
exp++
}
}
output = bOutput.Int64()
return
}
// Function Float returns the original float value of the current Number num
// computing the value of num.Value * 10^num.Exp.
func (num *Number) Float() (output float64) {
var bOutput = new(big.Float).SetInt(num.Value)
var exp = num.Exp.Int64()
for exp != 0 {
if exp > 0 {
bOutput.Mul(bOutput, fTen)
exp--
} else {
bOutput.Quo(bOutput, fTen)
exp++
}
}
output, _ = bOutput.Float64()
return
}