I'm want to get 15% of big.Int value, how can I do this?
new(big.Int).Mul(totalValue, new(big.Int).Div(new(big.Int).SetUint64(15), new(big.Int).SetUint64(100)))
returns 0
Order of operations can be really important with integer arithmetic when division is involved. Take the following code for example
int n = 200;
Console.WriteLine($"{n * (15 / 100)}");
Console.WriteLine($"{(n * 15) / 100}");
The first WriteLine will print 0 and the second will print 30.
Even though both lines should theoretically yield the same result because multiplication and division are associative. And they would actually produce the same result if you were using floating point math.
However, in this case integer math works a little differently. The problem is 15/100 yields 0 with integer division. So if the division is performed first, the result will always be 0.
Related
Is there any way to implement the Uint256 -> Uint256 function f(x) = floor(1.01 ^ x), using only a constant number of operations add, mul, sub, div, exp, all of those can only operate on integer numbers?
Use Newton's binomial series
(1+h)^x = 1+x*h + x*(x-1)/2*h^2 + x*(x-1)*(x-2)/6*h^3 + ...
= 1 + x*h*(1+(x-1)*h/2*(1+(x-2)*h/3*(1+...)))
To get a terminating computation, one would first have to reduce x, I'd think by multiples of log(2)/log(1.01).
Essentially, in the intermediate result you have to use some kind of fixed point arithmetics.
I would try fixed point. Let assume your Int256 is unsigned 8 bit int then try 8.8 or 8.16 or 8.32 fixed format. Depends on what precision you need.
let rewrite the number to a.b format and assume 8.16 (8.8 ignores too much of the 1.01 binary ones to my taste) so you got:
1.01^x = (1+0.01*65536/65536)^x = (1+655/65536)^x
a=1
b=655
now just compute integer pow for example with power by squaring see:
Power by squaring for negative exponents
The result then convert back to integer so either
floor (use just a)
round (increment a if b>32767 )
To avoid loops just encode the power by squaring into few copy paste lines (one for each bit).
btw this can be done with +,<< if you realize you are multiplying by:
1.01dec = 1.0000001010001111 bin
So you just can do shift and add for each binary 1 instead of mul in case mul is a problem ...
I need a way to compute how many times a fixed point number B is contained into a fixed point number A. Something like integer division but on non-integer operands.
I need to design an hardware block for this operation.
My first guess is to use division as shift and subtract and stop when I reach the fractional part but maybe you know better ways to find it.
If I understand you correctly you want the integer part of the fractional division, i.e.
C = floor(A / B)
Now, fractional division is not any different than integer division, besides adjusting the decimal point, if you represent A = a * 2^-n and B = b * 2^-m you get
C = floor(A / B) = floor((a / b) * 2^(-n-m))
So you can use the division algorithm for integers (which is essentially shift and subtract) unchanged and ignore (round down) the least significant n+m bits, or more efficiently just stop iterating once you've reached the decimal point.
I didn't know if this is a bug in Lua itself or if I was doing something wrong. I couldn't find anything about it anywhere. I am using Lua for Windows (Lua 5.1.4):
>return math.random(0, 1000000000)
1251258
This returns a random integer between 0 and 10000000000, as expected. This seems to work for all other values. But if I add a single 0:
>return math.random(0, 10000000000)
stdin:1: bad argument #2 to 'random' (interval is empty)
Any number higher than that does the same thing.
I tried to figure out exactly how high a number has to be to cause this and found something even weirder:
>return math.random(0, 2147483647)
-75617745
If the value is 2147483647 then it gives me negative numbers. Any higher than that and it throws an error. Any lower than that and it works fine.
That's 0b1111111111111111111111111111111 in binary, 31 binary digits exactly. I am not sure what that means though.
This unexpected behavior (bug?) is due to how math.random treats the input arguments passed in Lua 5.1. From lmathlib.c:
case 2: { /* lower and upper limits */
int l = luaL_checkint(L, 1);
int u = luaL_checkint(L, 2);
luaL_argcheck(L, l<=u, 2, "interval is empty");
lua_pushnumber(L, floor(r*(u-l+1))+l); /* int between `l' and `u' */
break;
}
As you may know in C, a standard int can represent values -2,147,483,648 to 2,147,483,647. Adding +1 to 2,147,483,647, like in your use-case, will overflow and wrap around the value giving -2,147,483,648. The end result is negative since you're multiplying a positive with a negative number.
Furthermore, anything above 2,147,483,647 will fail the luaL_argcheck due to overflow wraparound.
There are a few ways to address this problem:
Upgrade to Lua 5.2. That one has since fixed this issue by treating the input arguments as lua_Number instead.
Switch to LuaJIT which does not have this integer overflow issue.
Patch the Lua 5.1 source yourself with the fix and recompile.
Modify your random range so it does not overflow.
If you need a range that is larger than what the random function supports (32 bit signed integers or 2^31 due to sign bit, because math.random is at C level), but smaller than the range of Lua "number" type (based on What is the maximum value of a number in Lua?, 2^52, or maybe even 2^53), you could try generating two random numbers: scale the first to the range desired; add the second to "fill the gap". For example, say you want a range of 0 to 2^36. The largest from math.random is 2^31. So you could do:
-- 2^36 = 2^31 * 2^5 so
scale = 2^5
baseRand = scale * math.random(0, 2^31)
-- baseRand is now between 0 and 2^36 but there are gaps of 2^5 in the set
-- of possible values; fill the gaps with second random number:
fillGap = math.random(0, 2^5)
randNum = baseRand + fillGap
This will work as long as the desired range is less than the Lua interpreter's maximum for Lua numbers, which is a configurable compile time parameter but if you use stock build it is 2^52, a very large number (although not as large as largest long integer, 2^63).
Note also that largest positive N-bit integer is 2^N-1 (not 2^N), but the above technique can be applied to any range, you could have for instance scale = 10^6 then randNum = 10^6 * math.random(0, 10^8) + math.random(0, 10^6).
I need to write an algorithm that takes a positive integer x. If integer x is 0, the algorithm returns 0. If it's any other number, the algorithm returns 1.
Here's the catch. I need to condense the algorithm into one equation. i.e. no conditionals. Basically, I need a single equation that equates to 0 if x is zero and 1 if x > 0.
EDIT: As per my comment below. I realize that I wasn't clear enough. I am entering the formula into a system that I don't have control over, hence they strange restrictions.
However, I learned a couple tricks that could be useful in the future!
In C and C++, you can use this trick:
!!x
In those languages, !x evaluates to 1 if x is zero and 0 otherwise. Therefore, !!x evaluates to 1 if x is nonzero and 0 otherwise.
Hope this helps!
Try return (int)(x > 0)
In every programming language I know, (int)(TRUE) == 1 and (int)(FALSE) == 0
Assuming 32-bit integers:
int negX = -x;
return negX >> 31;
Negating x puts a 1 in the highest bit. Shifting right by 31 places moves that 1 to the lowest bit, and fills with 0s. This does nothing to a 0, but converts all positive integers to 1.
This is basically the sign function, but since you specified a positive integer input, you can drop the part that converts negative numbers to -1.
Since virtually every system I know of uses IEEE-754 representation for floating-point numbers, you could just rely on its behavior (namely, that 0.0 / 0.0 is NaN, and NaN != NaN). Pseudo-C (-Java, ...) follows:
float oneOrNAN = (float)(x) / (float)(x);
return oneOrNAN == oneOrNAN;
Like I said, I wasn't clear enough in my problem description. When I said equation, I meant a purely algebraic equation.
I did find an acceptable solution: Y = X/(X - .001)
If it's zero you get 0/ -.001 which is just 0. Any other number, you get 5/4.999 which is close enough to 1 for my particular situation.
However, this is interesting:
!!x
Thanks for the tip!
I am looking for a hash-function which operates on a small integer (say in the range 0...1000) and outputs a 64 bit int.
The result-set should look like a random distribution of 64 bit ints: a uniform distribution with no linear correlation between the results.
I was hoping for a function that only takes a few CPU-cycles to execute. (the code will be in C++).
I considered multiplying the input by a big prime number and taking the modulo 2**64 (something like a linear congruent generator), but there are obvious dependencies between the outputs (in the lower bits).
Googling did not show up anything, but I am probably using wrong search terms.
Does such a function exist?
Some Background-info:
I want to avoid using a big persistent table with pseudo random numbers in an algorithm, and calculate random-looking numbers on the fly.
Security is not an issue.
I tested the 64-bit finalizer of MurmurHash3 (suggested by #aix and this SO post). This gives zero if the input is zero, so I increased the input parameter by 1 first:
typedef unsigned long long uint64;
inline uint64 fasthash(uint64 i)
{
i += 1ULL;
i ^= i >> 33ULL;
i *= 0xff51afd7ed558ccdULL;
i ^= i >> 33ULL;
i *= 0xc4ceb9fe1a85ec53ULL;
i ^= i >> 33ULL;
return i;
}
Here the input argument i is a small integer, for example an element of {0, 1, ..., 1000}. The output looks random:
i fasthash(i) decimal: fasthash(i) hex:
0 12994781566227106604 0xB456BCFC34C2CB2C
1 4233148493373801447 0x3ABF2A20650683E7
2 815575690806614222 0x0B5181C509F8D8CE
3 5156626420896634997 0x47900468A8F01875
... ... ...
There is no linear correlation between subsequent elements of the series:
The range of both axes is 0..2^64-1
Why not use an existing hash function, such as MurmurHash3 with a 64-bit finalizer? According to the author, the function takes tens of CPU cycles per key on current Intel hardware.
Given: input i in the range of 0 to 1,000.
const MaxInt which is the maximum value that cna be contained in a 64 bit int. (you did not say if it is signed or unsigned; 2^64 = 18446744073709551616 )
and a function rand() that returns a value between 0 and 1 (most languages have such a function)
compute hashvalue = i * rand() * ( MaxInt / 1000 )
1,000 * 1,000 = 1,000,000. That fits well within an Int32.
Subtract the low bound of your range, from the number.
Square it, and use it as a direct subscript into some sort of bitmap.