4 ms·
To me, it's because it doesn't feel reliable by default. For example: Python: >>> 2**2**2**2**2 Traceback (most recent call last): File "<stdin>", lin
by xyproto 4y ago
To me, it's because it doesn't feel reliable by default. For example:
Python:
>>> 2**2**2**2**2
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: Exceeds the limit (4300) for integer string conversion
C:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int main(int argc, char* argv[])
{
printf("%.0lf\n", pow(pow(pow(pow(pow(2, 2), 2), 2), 2), 2));
return EXIT_SUCCESS;
}
% gcc -o main -std=c18 -O2 -pipe -fPIC -fno-plt -fstack-protector-strong main.c && ./main
4294967296
Julia:
julia> 2^2^2^2^2
0
- psyklic 4y agoIt's unclear what "reliable by default" is referring to. The deep learning community already uses Python and C++. Python computes the correct result here, since it uses bigints by default. (The error is when formatting it for display, easily worked around by an extra line of code.) In the C and Julia cases, it's well-known to use bigints when working with large numbers. For example: julia> BigInt(2)^2^2^2^2
- xyproto 4y agoReturning the wrong result without a complaint.
- psyklic 4y agoI am wondering which languages have this "reliable by default" property. For example, even Mathematica stores floating-point numbers as double-precision. Mathematica (default settings): In := 0.2 - 0.10000001 Out = 0.1 Out of curiosity, why is this property specifically desirable for deep learning applications? A neural net typically uses floats, and I suspect it would be robust to very minor error.
- photon-torpedo 4y ago> pow(pow(pow(pow(pow(2, 2), 2), 2), 2), 2)) The Julia equivalent is: julia> ((((2^2)^2)^2)^2)^2 4294967296 Julia's ^ is right-associative.
- eesmith 4y agoThe ValueError in "2*2*2*2*2" is a recent change to limit denial of service attacks. See https://github.com/python/cpython/issues/95778 https://github.com/python/cpython/issues/95778 . In short, the value you want has 19729 digits in base-10, the conversion from the internal base-30 representation to base-10 cannot be done in linear time, and conversion from arbitrary-length/untrusted data input to integer is very common, making it hard to audit. The limit of 4300 can be changed using https://docs.python.org/3.11/library/stdtypes.html#int-max-str-digits https://docs.python.org/3.11/library/stdtypes.html#int-max-s... . Set it to 0 for unlimited. (I wonder if there will be a thread-local context for this setting in the future, or some other way to bypass the limit on an as-needed basis.) In any case, your Python and C examples compute different values because you mistook a right-associative operator for a left-associative operator. On my Python 3.12.0a0: >>> pow(pow(pow(pow(pow(2, 2), 2), 2), 2), 2) 4294967296 >>> ((((2**2)**2)**2)**2)**2 4294967296 >>> big = 2**2**2**2**2 # a**b is right-associative in Python >>> len(str(big)) Traceback (most recent call last): File "<stdin>", line 1, in <module> ValueError: Exceeds the limit (4300) for integer string conversion >>> import sys >>> sys.set_int_max_str_digits(0) >>> len(str(big)) 19729 Your C example, when written to match your Python example, correctly gives "inf" as it is larger than the range of double, which is pow()'s return type: #include <stdio.h> #include <stdlib.h> #include <math.h> int main(int argc, char* argv[]) { printf("%.0lf\n", pow(2, pow(2, pow(2, pow(2, pow(2, 2)))))); return EXIT_SUCCESS; } % gcc -o main -std=c18 -O2 -pipe -fPIC -fno-plt -fstack-protector-strong main.c && ./main inf Your C program, when written to match your Julia example for a 32-bit architecture (which uses Int32 by default), also gives 0, as it overflows 32-bit signed integers: #include <stdio.h> #include <stdlib.h> #include <math.h> int main(int argc, char* argv[]) { int value = 2; value = value * value; value = value * value; value = value * value; value = value * value; value = value * value; printf("%d\n", value); return EXIT_SUCCESS; } % gcc -o main -std=c18 -O2 -pipe -fPIC -fno-plt -fstack-protector-strong main.c && ./main 0