sqrt(-1)应该等于什么?

149 阅读2分钟

sqrt(-1)应该等于什么?

先来看看在几种主流的编程语言(Leetcode支持的编程语言)中,sqrt(-1)的值都分别是什么。

可以把下面的代码片段复制到Leetcode 50. Pow(x, n)这道题给出的函数内,然后执行并验证结果。这样可以省去大量与计算sqrt(-1)无关的代码,还不用搭建各种语言的运行环境了。

计算结果可以分为几类:

  • -nan:C、C++、Swift
  • nan:PHP
  • NaN:Java、C#、JavaScript、TypeScript、Go、Rust、Kotlin、Scala、Dart
  • 报错:Python、Ruby、Erlang、Elixir
  • 复数:Racket

没想到还真有返回复数和报错的语言。

这么看来,Martin Fowler在《Refactoring》一书中的如下描述,并不适用于所有语言。

You often see special cases with numbers. Floating points in Java have special cases for positive and negative infinity and for not a number (NaN). The value of special cases is that they help reduce dealing with errors. Floating point operations don't throw exceptions. Doing any operation with NaN yields another NaN in the same way that accessors on null objects usually result in other null objects.

—— Refactoring Other Special Cases

-nan

C、C++

// C、C++
return sqrt(-1);

// 结果:-nan

Swift

// Swift
return sqrt(-1) 

// 结果:-nan

nan

PHP

// PHP
return sqrt(-1);

// 结果:nan

NaN

Java

// Java
// return Math.sqrt(-1);    // 直接`return` Leetcode会报错:java.lang.NumberFormatException: Infinite or NaN

System.out.println(Math.sqrt(-1));
return 0;

// 结果:NaN

C#

// C#
return Math.Sqrt(-1);

// 结果:NaN

JavaScript、TypeScript

// JavaScript、TypeScript
return Math.sqrt(-1);

// 结果:NaN

Go

// Go
return math.Sqrt(-1)

// 结果:NaN

Rust

// Rust
(-1.0_f64).sqrt() // `-1.0_f64`的括号不能省略

// 结果:NaN

Kotlin、Scala

// Kotlin、Scala
return sqrt(-1.0)    // 直接`return` Leetcode会报错:Exception in thread "main" java.lang.NumberFormatException: Infinite or NaN

val result = sqrt(-1.0)
println(result)
return 0.0

// 结果:NaN

Dart

// Dart
return sqrt(-1);

// 结果:NaN

报错

Python

# Python
return math.sqrt(-1)

# 结果:ValueError: math domain error

import numpy
return numpy.sqrt(-1)

# 结果:nan

Ruby

# Ruby
return Math.sqrt(-1)

# 结果:Numerical argument is out of domain

Erlang

% Erlang
Result = math:sqrt(-1),
io:format("~p~n", [Result]),
0.0.

% 结果:Line 3: exception error: badarith

Elixir

# Elixir
result = :math.sqrt(-1)
IO.inspect(result)
0.0

# 结果:(ArithmeticError) bad argument in arithmetic expression

复数

Racket

; Racket
(displayln (sqrt -1))    ; 直接`return` Leetcode会报错:
                         ; broke its own contract
                         ; promised: flonum?
                         ; produced: 0+1i
0.0

; 结果:0+1i