原谅设计得很糟糕的伪代码,但我希望它能明白这一点:
float sqrt takes float n : [0,inf)
// fancy algorithm
return result
void main
x = sqrt -1 // Compilation error
y = sqrt float.max // This works
z = (y + 1) * (y + 1) // Compilation error (this would result in overflow)
在编译期间,编译器分析sqrt
函数并将其表征为
sqrt : [0,float.max] -> [0, sqrt float.max[
它通过对+, -, *, /
操作员做同样的事情来做到这一点。
在main
函数中,第一条语句不编译,因为sqrt
不接受负输入。第三条语句无法编译,因为*
运算符只接受会导致输出的输入[float.min, float.max]
。