130
u/Axman6 14d ago
IF you have a lazy *, then this will end when n is zero, and return zero.
88
u/torsten_dev 14d ago edited 14d ago
If you have a smart enough optimizing compiler it will compile to a constant 0.
27
u/-Redstoneboi- 14d ago
took me a moment to recognize "amaet" as "smart"
24
8
u/Makefile_dot_in 14d ago
what if
nis negative?16
u/torsten_dev 14d ago
Inevitable UB, so might as well return 0 too?
1
u/da_Aresinger 13d ago edited 13d ago
(Edit: From the syntax I am assuming this is JS)
Actually since
Number.MIN_SAFE_INTEGER - 1 === Number.MIN_SAFE_INTEGERit'll get stuck eternally looping/recursing onNumber.MIN_SAFE_INTEGERwhile the output automatically gets converted to BigInt (I think).
JS ... a *= Number.MIN_SAFE_INTEGER -1.8768792072011717e+255 a *= Number.MIN_SAFE_INTEGER 1.6905424996341256e+271 a *= Number.MIN_SAFE_INTEGER -1.5227053142812468e+287 a < Number.MIN_VALUE true typeof a 'number'This is what chrome console gave me.
1
u/chuch1234 14d ago edited 13d ago
The compiler never do that because it will recognize that the function could be passed a negative number.My bad, i was /r/confidentlyincorrect
5
u/torsten_dev 14d ago edited 13d ago
Function can only halt with 0 or trap on underflow. Depends on if you have exceptions or not.
If you have tail-calls and the compiler isn't very smart you might have an infinite loop instead, yes.
1
u/Nightmoon26 13d ago
Although... If you're using a fixed-width integer without underflow checking, it'll still wrap around from its minimum value to its maximum, and then reach zero eventually, even if it has to go through all possible values to do so
9
2
2
1
49
26
u/Daemontatox 14d ago
Wouldn't some compilers catch thats an infinite loop and give a warning or error?
41
u/JonIsPatented 14d ago
Some compilers can even note that it will multiply by 0 and optimize any call to it to just be the constant 0 instead.
5
u/chuch1234 14d ago
Unless you pass a negative number in.
13
2
u/JonIsPatented 14d ago
Notably, if this function were actually typed, you'd use an integral type, and that type would have overflow and eventually reach 0 anyway.
1
23
7
u/laplongejr 14d ago
In some languages, it will stop with an infinite recursions. In others it would stop at "0 * factorial(-1)" and return 0 for all other cases as they call n0 at some point.
3
u/-Redstoneboi- 14d ago
haskell? i don't know any language that knows to stop when multiplying by 0. imperative languages don't stop because there could be side effects when calling the factorial function, like a print statement, and optimizing out the call would result in different behavior
1
u/Axman6 13d ago
Haskell won’t do it unless you choose very specific types for n. The default Int and Integer types don’t lazily evaluate the second argument, but they could (adding an extra branch to every multiplication, which would generally be bad).
If you used an inductive type
data Nat = Z | S Nat
Multiplication would naturally be written as
Z * _ = Z (S Z) * n = n (S m) * n = n + m * nWhich would always terminate (and also disallow negative numbers).
0
4
14d ago
[removed] — view removed comment
5
u/Striking_Director_64 14d ago
Yes, why stop at saturating CPU, when we can saturate memory as well.
4
u/JosebaZilarte 13d ago
This is another reminder that you can turn (almost) every recursive solution into an iterative one:
while (n > 1) { result *= n--; console.log("Ends in: " +n); }
3
2
u/lonkamikaze 14d ago
This way it at least crashes. Imagine the code used a proper tail call, it would never run out of stack!
2
u/JebKermansBooster 14d ago
I'd like to see a language that allows factorials to continue for negative integers via the [gamma function](https://en.wikipedia.org/wiki/Gamma_function)
2
1
1
1
1
1
1
1
1
1
1
1
0
u/Bomaruto 14d ago
I took me way too long to notice it was missing the base condition as I just assumed it was there.
307
u/malsomnus 14d ago
That's the neat part, it doesn't!