Hot answers tagged

20

Problem is 4 & 5 fit in less that 256 bits (each). You end up with tiny uints in the constant expression, and then those aren't easily converted to the uint256, so ... cast the type explicitly. uint x = uint(4)/uint(5); Takeaway is caution with constants because they may be cast in unexpected types. A sketchy idea: contract Divide { function ...


4

as an addition to @rob's answer you can use : function calcul(uint a, uint b, uint precision) view returns ( uint) { return a*(10**precision)/b; } If we divide using the function above 7/3 with a precision of 5 it will output 233333 which means 7/3=2.33333. The conversion to float can be done in the front-end.


4

After posting the question, I realised I gave the answer myself. I simply have to check if both x and y are odd numbers and, if yes, add 1 to the result: function avg(uint256 x, uint256 y) external returns (uint256 result) { result = x / 2 + y / 2; if (x % 2 == 1 && y % 2 == 1) { result += 1; } } Update: I ended up optimising the ...


4

As per the Solidity cheatsheet, mulmod is a function available at the global scope. mulmod(uint x, uint y, uint k) returns (uint): compute (x * y) % k where the multiplication is performed with arbitrary precision and does not wrap around at 2**256. Assert that k != 0 starting from version 0.5.0. Some examples: mulmod(3, 4, 5) is equal to 2. mulmod(2**256 ...


4

x * y < WAD / 2 ==> x * y + WAD / 2 < WAD ==> (x * y + WAD / 2) / WAD == 0


4

Looking at the documentation for Solidity 0.8.0 it doesn't seem so like the unchecked block in bar disables the safety checks in foo.. The setting only affects the statements that are syntactically inside the block. Functions called from within an unchecked block do not inherit the property. https://docs.soliditylang.org/en/v0.8.0/control-structures.html#...


3

I can think of four ways, ordered below from least efficient to most efficient. I didn't include any gas costs because they vary based on the value of x, whether you use the compiler optimizer, what's the highest power of ten supported etc. The code snippets are written for Solidity v0.8 and they use table lookups with values up to 10**5, for brevity, but ...


2

Maintain every non-integer entity in your code as a pair of numerator and denominator. If the same denominator is used everywhere (for example, 100 in your case), then you can maintain only the numerators (for example, 108383, 825 and 13137 in your case). Whenever you apply an arithmetic computation, try to "postpone" the operation / (or div if you'...


2

Good Vibes is right. Modulo and you're done. The discussion gives me the impression that you don't fully understand how the remainder function solves it. There is no divide by zero, no need to multiply x 10. Just do: random % array.length and you will get a number from 0 to array.length-1 which is precisely what you want. 0 % <anything> = 0 3 % 9 = 3 ...


2

Yes, there is at least one situation where overflow can occur. I don't know about underflows though. When you divide the minimum of a signed type by -1, you get the mirror image of that number in the unsigned part, but the unsigned type only goes up to that number minus 1. function div_overflow() public pure returns (int16 result) { int16 x = type(int16)....


2

The compiler does accept decimals in an expression if the resulting value is valid. For example uint256 x = 0.23 * 100 is valid. The expression uint256 y = 0.123 * 100 fails to compile with TypeError: Type rational_const 123 / 10 is not implicitly convertible to expected type uint256.


2

Solidity had a historical issue with arithmetic overflows and underflows, that's why having SafeMath enabled was a necessity back in the day. SafeMath has been made obsolete starting from Solidity v0.8.0, as internal checking for arithmetic operations was added by default. I would suggest to always use the latest version of Solidity as possible.


2

Writing 5.add(7) is a syntax sugar for add(5, 7). So first expression 5.add(7.add(8)) is add(5, add(7, 8)) and the second one 5.add(7).add(8) is add(add(5, 7), 8). In the particular case of SafeMath's add both expression will arrive at the same result. For other functions like sub and div make sure they are in the correct order. The last expression 5.add(7 + ...


2

Yes, modulo is cheaper in unchecked arithmetic! Take the following code: pragma solidity ^0.8.0; contract Modulos { function foo(uint256 x, uint256 y) external view returns (uint256 result, uint256 gasUsed) { uint256 startGas = gasleft(); result = x % y; gasUsed = startGas - gasleft(); } function bar(uint256 x, ...


2

You would use the shift operator. In your example: uint8 value = 9; uint256 mask = 1 << value; See https://docs.soliditylang.org/en/v0.8.10/types.html#integers


1

I managed to implement both floor and ceil as follows. The ABDKMath64x64.toInt function essentially floors the signed fixed point number to a signed integer, hence the following would hold true: toInt(-18444899399302180000) == -1 i.e. floor(-0.9999) == -1 toInt(0) == 0 i.e. floor(0) == 0 toInt(18444899399302180000) == 0 i.e. floor(0.9999) == 0 toInt(...


1

Division by zero is an exception that will result in a reverted transaction. function foo(uint num, uint den) public pure returns(uint result) { if(den == 0) return 0; // there is no "correct" result, so decide what to do result = num / den; } There are other subtleties around division - no floats, precision, truncation - setting those aside ...


1

Looking at the latest Solidity docs there are both operation for integers available: ** - exponentiation ^ - bitwise exclusive or So in your case only ** makes sense. I am not aware of any version where this was different.


1

solidity (prior to version 0.8.x) doesn't check for over/underflows. That means that if you're if you're trying to set it to less than 0 (or more than (2^256 -1) it's going to wrap around (0-1 = 2^256-1 and (2^256-1) +1 = 0 ). The way we used to deal with this prior to 0.8 is to use the SafeMath library, which does pretty much what you've described.


1

Set Y to be (1/X). X being the sum of all units staked (100 in your first example, 120 in second example). If you divide each user's stake by the total amount staked, you get the user's percentage of the bag.


1

Use PRBMath! // SPDX-License-Identifier: Unlicense pragma solidity >=0.8.4; import "prb-math/contracts/PRBMathSD59x18.sol"; contract SignedConsumer { using PRBMathSD59x18 for int256; /// @notice Calculates x*PI÷1e18 while handling possible intermediary overflow. function multiplyByPi(int256 x) external pure returns (int256 result) { ...


1

This kind of rounding issues are quite typical in crypto projects. You have two options: 1) Try to decide who should get more (or less) 2) Do something else with the leftovers (also called dust). Often it's simply not worth it to start calculating who should get more - especially as calculations are not accurate in Solidity (due to no decimal numbers). So ...


1

That's a very good question. It touches upon a detail that is probably not very well known, even though it's documented (Rational and Integer Literals): Number literal expressions retain arbitrary precision until they are converted to a non-literal type (i.e. by using them together with a non-literal expression or by explicit conversion). This means that ...


1

You could roughly estimate the 24 hr reward as follows: dailyReward = (your_hashrate / api.nethash) * api.block_reward24 * (6*60*24) You need to multiply by 6*60*24 to convert the block reward to the total block rewards of a 24hr period, since a new ETH block is mined every 10 seconds. block_reward24 is safer to use than block_reward, since block_reward24 ...


1

SafeMath is used to protect your contract against math errors, such as overflow (adding uint above the max uint, for instance). SafeMath will revert the transaction if bad math happens in a transaction. It may very slightly increase the gas used for the transaction, but the benefit of safety is generally worth it. SafeMath is no longer needed if you use ...


1

Maker Protocol does not use or store an annual rate and there is no representation for it internally. All rates are in per-second which uses the RAY number format which are regular uint256 values and are always handled by special math functions like rmul or rdiv which automatically consider the 27 right most numbers as the decimal part of the RAY fixed-point ...


1

Literal expressions have arbitrary precision until converted (eg. casted) to a non-literal type. In this example, the literal expression 5/4 is an internal rational constant type with unlimited precision, and cannot be implicitly downcasted to a uint256. This is apparently a restriction on rationals imposed by the compiler. Note that for whole-number ...


1

Turning a comment into an answer: As far as I know, floating-point variants are not supported in Solidity because not every machine (i.e., HW architecture) used by every miner is guaranteed to implement the same floating-point standard (or to even implement any floating-point standard to begin with).


1

You may use fixed point math library such as ABDK Math 64.64. It has method divi that divides one integer by another and returns the result as binary fixed point number with 64 binary digits after dot.


Only top voted, non community-wiki answers of a minimum length are eligible