first commit
This commit is contained in:
commit
79563f0a88
1215
ABDKMathQuad.sol
Normal file
1215
ABDKMathQuad.sol
Normal file
File diff suppressed because it is too large
Load Diff
53
conv.py
Normal file
53
conv.py
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
from decimal import Decimal, getcontext
|
||||||
|
|
||||||
|
def convert_quad_hex_to_float(hex_str):
|
||||||
|
# Set high enough precision
|
||||||
|
getcontext().prec = 100
|
||||||
|
|
||||||
|
# Remove 0x prefix if present
|
||||||
|
hex_str = hex_str.lower().lstrip('0x')
|
||||||
|
|
||||||
|
if len(hex_str) != 32:
|
||||||
|
raise ValueError("Hex string must be exactly 32 characters (128 bits).")
|
||||||
|
|
||||||
|
# Convert to integer, then to binary string
|
||||||
|
int_val = int(hex_str, 16)
|
||||||
|
bin_str = f"{int_val:0128b}"
|
||||||
|
|
||||||
|
# Extract parts
|
||||||
|
sign_bit = int(bin_str[0], 2)
|
||||||
|
exponent_bits = bin_str[1:16]
|
||||||
|
fraction_bits = bin_str[16:]
|
||||||
|
|
||||||
|
# Interpret fields
|
||||||
|
sign = (-1) ** sign_bit
|
||||||
|
exponent = int(exponent_bits, 2)
|
||||||
|
bias = 16383 # Bias for quadruple precision
|
||||||
|
|
||||||
|
# Special cases
|
||||||
|
if exponent == 0 and int(fraction_bits, 2) == 0:
|
||||||
|
return Decimal(sign * 0)
|
||||||
|
elif exponent == 0x7FFF:
|
||||||
|
if int(fraction_bits, 2) == 0:
|
||||||
|
return Decimal('Infinity') if sign > 0 else Decimal('-Infinity')
|
||||||
|
else:
|
||||||
|
return Decimal('NaN')
|
||||||
|
|
||||||
|
# Compute fraction
|
||||||
|
fraction = Decimal(0)
|
||||||
|
for i, bit in enumerate(fraction_bits):
|
||||||
|
if bit == '1':
|
||||||
|
fraction += Decimal(1) / (Decimal(2) ** (i + 1))
|
||||||
|
|
||||||
|
# Add implicit 1 if normalized
|
||||||
|
if exponent != 0:
|
||||||
|
fraction = Decimal(1) + fraction
|
||||||
|
exponent_val = exponent - bias
|
||||||
|
else:
|
||||||
|
# Subnormal
|
||||||
|
exponent_val = 1 - bias
|
||||||
|
|
||||||
|
# Compute final value
|
||||||
|
value = Decimal(sign) * fraction * (Decimal(2) ** exponent_val)
|
||||||
|
return value
|
||||||
|
print(convert_quad_hex_to_float("0x4000921fb54442d18469898cc51701b8"))
|
||||||
72
pi.sol
Normal file
72
pi.sol
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
import './ABDKMathQuad.sol';
|
||||||
|
|
||||||
|
|
||||||
|
contract pi {
|
||||||
|
using ABDKMathQuad for bytes16;
|
||||||
|
|
||||||
|
// Immutable variables (set once in constructor)
|
||||||
|
bytes16 public immutable C_426880;
|
||||||
|
bytes16 public immutable C_10005;
|
||||||
|
bytes16 public immutable C_13591409;
|
||||||
|
bytes16 public immutable C_545140134;
|
||||||
|
bytes16 public immutable C_640320;
|
||||||
|
bytes16 public immutable C_12;
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
C_426880 = ABDKMathQuad.fromInt(426880);
|
||||||
|
C_10005 = ABDKMathQuad.fromInt(10005);
|
||||||
|
C_13591409 = ABDKMathQuad.fromUInt(13591409);
|
||||||
|
C_545140134 = ABDKMathQuad.fromUInt(545140134);
|
||||||
|
C_640320 = ABDKMathQuad.fromUInt(640320);
|
||||||
|
C_12 = ABDKMathQuad.fromUInt(12);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Compute factorial of n (as uint256), note: limited by gas
|
||||||
|
function factorial(uint256 n) internal pure returns (uint256) {
|
||||||
|
if (n == 0 || n == 1) return 1;
|
||||||
|
uint256 result = 1;
|
||||||
|
for (uint256 i = 2; i <= n; i++) {
|
||||||
|
result *= i;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Compute power (uint256 base ^ uint256 exp)
|
||||||
|
function pow(uint256 base, uint256 exp) internal pure returns (uint256) {
|
||||||
|
uint256 result = 1;
|
||||||
|
for (uint256 i = 0; i < exp; i++) {
|
||||||
|
result *= base;
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Compute one term of the Chudnovsky series for k
|
||||||
|
function chudnovskyTerm(uint256 k) internal pure returns (bytes16 numerator, bytes16 denominator) {
|
||||||
|
uint256 sixKFact = factorial(6 * k);
|
||||||
|
uint256 kFact = factorial(k);
|
||||||
|
uint256 threeKFact = factorial(3 * k);
|
||||||
|
|
||||||
|
// Use int256 to allow negative multiplication
|
||||||
|
int256 numeratorInt = int256(sixKFact) * int256(13591409 + 545140134 * k);
|
||||||
|
if (k % 2 == 1) numeratorInt *= -1; // Correctly applies sign
|
||||||
|
|
||||||
|
uint256 denominatorInt = threeKFact * (kFact ** 3) * pow(640320, 3 * k);
|
||||||
|
|
||||||
|
numerator = ABDKMathQuad.fromInt(numeratorInt); // Ensure ABDKMathQuad supports int
|
||||||
|
denominator = ABDKMathQuad.fromUInt(denominatorInt);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Approximate pi using n terms (WARNING: only small n due to gas and uint256 limits)
|
||||||
|
function computePi(uint256 n) public view returns (bytes16) {
|
||||||
|
bytes16 sum = ABDKMathQuad.fromUInt(0);
|
||||||
|
|
||||||
|
for (uint256 k = 0; k < n; k++) {
|
||||||
|
(bytes16 num, bytes16 den) = chudnovskyTerm(k);
|
||||||
|
sum = sum.add(num.div(den));
|
||||||
|
}
|
||||||
|
|
||||||
|
bytes16 sqrt10005 = ABDKMathQuad.sqrt(C_10005);
|
||||||
|
bytes16 factor = C_426880.mul(sqrt10005);
|
||||||
|
return factor.div(sum);
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user