-
Notifications
You must be signed in to change notification settings - Fork 21
/
03.02 数值(Number)
116 lines (80 loc) · 3.61 KB
/
03.02 数值(Number)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
3.2 数值(Number)
Racket的数值(number)可以是精确的也可以是不精确的:
1、精确的数字是:
1)一个任意大的或小的整数,比如:5,99999999999999999,或-17;
2)一个有理数,即精确的两个任意小的或大的整数比,比如:1/2,99999999999999999/2,或-3/4;
3)一个复数,带有精确的实部和虚部(即虚部不为零),比如:1+2i或1/2+3/4i。
2、一个不精确的数字是:
1)一个数的一个IEEE浮点表示,比如:2.0或3.14e+87,其中IEEE无穷大和非数书写为:+inf.0,-inf.0和+nan.0(或-nan.0);
2)一个带有实部和虚部配对的复数的IEEE浮点表示,比如:2.0+3.0i或-inf.0+nan.0i;一种特殊情况是,一个不精确的复数可以有一个精确的零实部和一个不精确的虚部。
对一个小数点或指数的说明符进行不精确数字打印,对整数和分数进行精确数字打印。用同样的约定申请读入数值常数,但#e或#i可以前缀数值以解析一个精确的或不精确的数值。前缀#b、#O和#x指定二进制、八进制和十六进制数值的解释。
例如:
> 0.5
0.5
> #e0.5
1/2
> #x03BB
955
计算涉及到精确的数值产生不精确的结果,这样的情况对数据造成一种污染。注意,然而,Racket没有提供"不精确的布尔值",所以对不精确的数字的比较分支计算却能产生精确的结果。exact->inexact和inexact->exact程序在两种类型的数值之间转换。
例如:
> (/ 1 2)
1/2
> (/ 1 2.0)
0.5
> (if (= 3.0 2.999) 1 2)
2
> (inexact->exact 0.1)
3602879701896397/36028797018963968
当精确的结果需要表达实际的非有理数数值,不精确的结果也由像sqrt、log和sin这样的程序产生。Racket只能代表有理数和有理数配对的复数。
例如:
> (sin 0) ; 有理数...
0
> (sin 1/2) ; 非有理数...
0.479425538604203
在性能方面,小整数的计算通常是最快的,其中“小”意味着这个数字比有符号数值的机器字长要小一点。具有非常大的精确整数或非整精确数的计算要比不精确数的计算代价要高昂得多。
(define (sigma f a b)
(if (= a b)
0
(+ (f a) (sigma f (+ a 1) b))))
> (time (round (sigma (lambda (x) (/ 1 x)) 1 2000)))
cpu time: 400 real time: 103 gc time: 0
8
> (time (round (sigma (lambda (x) (/ 1.0 x)) 1 2000)))
cpu time: 1 real time: 0 gc time: 0
8.0
在针对通常的number?的加法中,整数类、有理数类、实类(总是有理数)和复数都以通常的方式定义,并被程序integer?、rational?、real?和complex?所识别。一些数学过程只接受实数,但大多数实现了对复数的标准扩展。
例如:
> (integer? 5)
#t
> (complex? 5)
#t
> (integer? 5.0)
#t
> (integer? 1+2i)
#f
> (complex? 1+2i)
#t
> (complex? 1.0+2.0i)
#t
> (abs -5)
5
> (abs -5+2i)
abs: contract violation
expected: real?
given: -5+2i
> (sin -5+2i)
3.6076607742131563+1.0288031496599335i
=过程比较数值相等的数值。如果给定不精确和精确的数字进行比较,它实际上会在比较之前将不精确数字转换为精确数字。eqv?(乃至equal?)程序,相反,程序比较既是精确数而且数值上相等的数值。
例如:
> (= 1 1.0)
#t
> (eqv? 1 1.0)
#f
当心涉及不精确的数字比较,由于其性质会有令人惊讶的行为。即使是简单的不精确的数字也许并不意味着你能想到他们的意思;例如,当一个二进制IEEE浮点数可以表示为1/2精确数,它只能近似于1/10:
例如:
> (= 1/2 0.5)
#t
> (= 1/10 0.1)
#f
> (inexact->exact 0.1)
3602879701896397/36028797018963968