day5 浮点数
parent
278314bd6f
commit
340bf90010
|
@ -17,6 +17,9 @@ func main() {
|
|||
}
|
||||
|
||||
func handler(w http.ResponseWriter, r *http.Request) {
|
||||
vars := r.URL.Query()
|
||||
a := vars["a"][0]
|
||||
fmt.Fprintf(w, a)
|
||||
mu.Lock()
|
||||
count++
|
||||
mu.Unlock()
|
||||
|
|
|
@ -0,0 +1,60 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math"
|
||||
"reflect"
|
||||
)
|
||||
|
||||
// Go语言提供了两种精度的浮点数,float32和float64。
|
||||
// 它们的算术规范由IEEE754浮点数国际标准定义,该浮点数规范被所有现代的CPU支持。
|
||||
func main() {
|
||||
// 浮点数类型的取值范围可以从很微小到很巨大。浮点数的范围极限值可以在math包找到。
|
||||
fmt.Println(math.MaxFloat32)
|
||||
fmt.Println(math.MaxFloat64)
|
||||
|
||||
// 一个float32类型的浮点数可以提供大约6个十进制数的精度,
|
||||
// 而float64则可以提供约15个十进制数的精度;
|
||||
// 通常应该优先使用float64类型,
|
||||
// 因为float32类型的累计计算误差很容易扩散,并且float32能精确表示的正整数并不是很大
|
||||
// 译注:因为float32的有效bit位只有23个,其它的bit位用于指数和符号;
|
||||
// 当整数大于23bit能表达的范围时,float32的表示将出现误差
|
||||
var f1 float32 = 16777216 // 1 << 24
|
||||
fmt.Println(f1 == f1+1) // true
|
||||
|
||||
// 小数点前面或者后面的数都能被省略
|
||||
f2, f3 := .2345, 67.
|
||||
fmt.Println(reflect.TypeOf(f2), f2) // float64 0.2345
|
||||
fmt.Println(reflect.TypeOf(f3), f3) // float64 67
|
||||
|
||||
// 很小或很大的数最好用科学计数法书写,通过e或E来指定指数部分:
|
||||
const Avogadro = 6.02214129e23 // 阿伏伽德罗常数
|
||||
const Planck = 6.62606957e-34 // 普朗克常数
|
||||
|
||||
// 用Printf格式化输出浮点数时使用%g或者%f,可以用类似于%4.2f这种的格式输出
|
||||
// 4表示距离前一个操作数有4个tab,2表示保留两位小数输出
|
||||
fmt.Printf("%g", 22.33)
|
||||
fmt.Printf("\n %.4f %8.2f", 23.123456, 23.123456)
|
||||
fmt.Printf("\n %.4f %8.2f\n", 23.133442, 23343.13456)
|
||||
|
||||
// IEEE754浮点数标准中定义的特殊值的创建和测试:正无穷大和负无穷大,
|
||||
// 分别用于表示太大溢出的数字和除零的结果;
|
||||
//还有NaN非数,一般用于表示无效的除法操作结果0/0或Sqrt(-1).
|
||||
var z float64
|
||||
fmt.Println(z, -z, 1/z, -1/z, z/z) // "0 -0 +Inf -Inf NaN"
|
||||
// 函数math.IsNaN用于测试一个数是否是非数NaN,math.NaN则返回非数对应的值。
|
||||
// 虽然可以用math.NaN来表示一个非法的结果,
|
||||
// 但是测试一个结果是否是非数NaN则是充满风险的,因为NaN和任何数都是不相等的
|
||||
nan := math.NaN()
|
||||
fmt.Println(nan == nan, nan < nan, nan > nan) // "false false false"
|
||||
|
||||
// 如果一个函数返回的浮点数结果可能失败,最好的做法是用单独的标志报告失败,像这样:
|
||||
//func compute() (value float64, ok bool) {
|
||||
// // ...
|
||||
// if failed {
|
||||
// return 0, false
|
||||
// }
|
||||
// return result, true
|
||||
//}
|
||||
|
||||
}
|
|
@ -0,0 +1,59 @@
|
|||
// Surface computes an SVG rendering of a 3-D surface function.
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"math"
|
||||
)
|
||||
|
||||
const (
|
||||
width, height = 600, 320 // 画布大小
|
||||
cells = 100 // 单元格大小
|
||||
xyrange = 30.0 // 坐标轴范围 (-xyrange..+xyrange)
|
||||
xyscale = width / 2 / xyrange // x或y轴上每个单位长度的像素
|
||||
zscale = height * 0.4 // z轴上每个单位长度的像素
|
||||
angle = math.Pi / 6 // x、y轴的角度(=30°)
|
||||
)
|
||||
|
||||
var sin30, cos30 = math.Sin(angle), math.Cos(angle) // sin(30°), cos(30°)
|
||||
|
||||
var ConcerError error
|
||||
|
||||
func main() {
|
||||
fmt.Printf("<svg xmlns='http://www.w3.org/2000/svg' "+
|
||||
"style='stroke: grey; fill: white; stroke-width: 0.7' "+
|
||||
"width='%d' height='%d'>", width, height)
|
||||
for i := 0; i < cells; i++ {
|
||||
for j := 0; j < cells; j++ {
|
||||
ax, ay := corner(i+1, j)
|
||||
bx, by := corner(i, j)
|
||||
cx, cy := corner(i, j+1)
|
||||
dx, dy := corner(i+1, j+1)
|
||||
fmt.Printf("<polygon style='stroke: red;' points='%g,%g %g,%g %g,%g %g,%g'/>\n",
|
||||
ax, ay, bx, by, cx, cy, dx, dy)
|
||||
}
|
||||
}
|
||||
fmt.Println("</svg>")
|
||||
}
|
||||
|
||||
func corner(i, j int) (float64, float64) {
|
||||
// 求出网格单元(i,j)的顶点坐标(x,y)
|
||||
x := xyrange * (float64(i)/cells - 0.5)
|
||||
y := xyrange * (float64(j)/cells - 0.5)
|
||||
|
||||
// 计算曲面高度 z.
|
||||
z := f(x, y)
|
||||
|
||||
// 将(x, y, z)等角投射到二维SVG绘图平面上,坐标是(sx, sy)
|
||||
sx := width/2 + (x-y)*cos30*xyscale
|
||||
sy := height/2 + (x+y)*sin30*xyscale - z*zscale
|
||||
if math.IsNaN(sx) || math.IsNaN(sy) {
|
||||
ConcerError = fmt.Errorf("corner() 产生非数值")
|
||||
}
|
||||
return sx, sy
|
||||
}
|
||||
|
||||
func f(x, y float64) float64 {
|
||||
r := math.Hypot(x, y) // 到 (0,0) 的距离
|
||||
return math.Sin(r) / r
|
||||
}
|
|
@ -0,0 +1,76 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"math"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
const (
|
||||
width, height = 600, 320 // 画布大小
|
||||
cells = 100 // 单元格大小
|
||||
xyrange = 30.0 // 坐标轴范围 (-xyrange..+xyrange)
|
||||
xyscale = width / 2 / xyrange // x或y轴上每个单位长度的像素
|
||||
zscale = height * 0.4 // z轴上每个单位长度的像素
|
||||
angle = math.Pi / 6 // x、y轴的角度(=30°)
|
||||
)
|
||||
|
||||
var sin30, cos30 = math.Sin(angle), math.Cos(angle) // sin(30°), cos(30°)
|
||||
|
||||
var ConcerError error
|
||||
|
||||
func main() {
|
||||
|
||||
http.HandleFunc("/", surface)
|
||||
log.Fatal(http.ListenAndServe("localhost:8080", nil))
|
||||
}
|
||||
|
||||
func surface(w http.ResponseWriter, r *http.Request) {
|
||||
vars := r.URL.Query()
|
||||
stroke := vars.Get("stroke")
|
||||
if stroke == "" {
|
||||
stroke = "red"
|
||||
}
|
||||
fill := vars.Get("fill")
|
||||
if fill == "" {
|
||||
fill = "blue"
|
||||
}
|
||||
w.Header().Set("Content-Type", "image/svg+xml")
|
||||
fmt.Fprintf(w, `<svg xmlns='http://www.w3.org/2000/svg'
|
||||
style='stroke: %s; fill: %s; stroke-width: 0.7' width='%d' height='%d'>`,
|
||||
stroke, fill, width, height)
|
||||
fmt.Fprint(w, "\n")
|
||||
for i := 0; i < cells; i++ {
|
||||
for j := 0; j < cells; j++ {
|
||||
ax, ay := corner(i+1, j)
|
||||
bx, by := corner(i, j)
|
||||
cx, cy := corner(i, j+1)
|
||||
dx, dy := corner(i+1, j+1)
|
||||
fmt.Fprintf(w, "<polygon style='stroke: %s;' points='%g,%g %g,%g %g,%g %g,%g'/>\n",
|
||||
stroke, ax, ay, bx, by, cx, cy, dx, dy)
|
||||
}
|
||||
}
|
||||
fmt.Fprint(w, "</svg>")
|
||||
}
|
||||
func corner(i, j int) (float64, float64) {
|
||||
// 求出网格单元(i,j)的顶点坐标(x,y)
|
||||
x := xyrange * (float64(i)/cells - 0.5)
|
||||
y := xyrange * (float64(j)/cells - 0.5)
|
||||
|
||||
// 计算曲面高度 z.
|
||||
z := f(x, y)
|
||||
|
||||
// 将(x, y, z)等角投射到二维SVG绘图平面上,坐标是(sx, sy)
|
||||
sx := width/2 + (x-y)*cos30*xyscale
|
||||
sy := height/2 + (x+y)*sin30*xyscale - z*zscale
|
||||
if math.IsNaN(sx) || math.IsNaN(sy) {
|
||||
ConcerError = fmt.Errorf("corner() 产生非数值")
|
||||
}
|
||||
return sx, sy
|
||||
}
|
||||
|
||||
func f(x, y float64) float64 {
|
||||
r := math.Hypot(x, y) // 到 (0,0) 的距离
|
||||
return math.Sin(r) / r
|
||||
}
|
Loading…
Reference in New Issue