Logo
Published on

2.9.浮点类型

Authors
  • avatar
    Name
    xiaobai
    Twitter

1.什么是浮点数?

浮点数是用来表示实数(包含小数点的数)的数据类型。在 Python 中,浮点类型用 float 表示。

# 浮点数的例子
pi = 3.14159
temperature = -10.5
salary = 5000.00
scientific = 6.02e23  # 科学计数法:6.02 × 10²³

2.创建浮点数的方法

2.1.直接赋值

a = 3.14
b = -0.5
c = 10.0
d = 10.  # 等同于 10.0,但不推荐这种写法

2.2.科学计数法

avogadro = 6.02e23    # 6.02 × 10²³
electron_mass = 9.1e-31  # 9.1 × 10⁻³¹
large_number = 1.5e6  # 1,500,000
small_number = 2.3e-4 # 0.00023

2.3.类型转换

使用 float() 函数进行类型转换

# 从整数转换
float_from_int = float(42)      # 42.0

# 从字符串转换
float_from_str = float("3.14")  # 3.14
float_from_scientific = float("2.5e3")  # 2500.0

# 从布尔值转换
float_from_bool = float(True)   # 1.0 
float_from_false = float(False) # 0.0

2.4.除法运算自动产生浮点数

result1 = 10 / 2      # 5.0 (即使能整除也得到浮点数)
result2 = 7 / 3       # 2.3333333333333335
result3 = 5 / 1       # 5.0

3.以下内容不用看,Python全部学完后再看

4.浮点数的特点和精度问题

4.1.重要概念:浮点数不精确性

由于计算机使用二进制表示浮点数,有些十进制小数无法精确表示为二进制浮点数,这会导致精度问题。

# 经典的精度问题
a = 0.1 + 0.2
print(a)  # 输出:0.30000000000000004,而不是 0.3

b = 0.3
print(a == b)  # 输出:False

# 更多例子
print(0.1 + 0.1 + 0.1)  # 0.30000000000000004
print(1.1 + 2.2)        # 3.3000000000000003

为什么会出现这种情况?

  • 计算机使用二进制(基数为2)表示数字
  • 有些十进制小数在二进制中是无限循环的(比如 0.1)
  • 由于内存有限,只能存储近似值

4.2.验证浮点数精度

import sys

# 查看浮点数的精度信息
print(f"浮点数精度: {sys.float_info}")

# 输出示例:
# dig=15 表示大约15位十进制精度
# max=1.7976931348623157e+308 最大浮点数
# min=2.2250738585072014e-308 最小正浮点数

5.浮点数的运算

5.1.基本算术运算

x = 5.5
y = 2.2

print(x + y)   # 7.7
print(x - y)   # 3.3
print(x * y)   # 12.100000000000001 (精度问题)
print(x / y)   # 2.5
print(x ** 2)  # 30.25 (平方)

5.2.比较运算的注意事项

由于精度问题,直接比较浮点数可能不可靠:

# 不推荐的比较方式
a = 0.1 + 0.2
b = 0.3
print(a == b)  # False - 不应该这样比较!

# 推荐的比较方式:使用误差范围
def float_equal(x, y, tolerance=1e-9):
    return abs(x - y) < tolerance

print(float_equal(0.1 + 0.2, 0.3))  # True

# 或者使用 math.isclose() (Python 3.5+)
import math
print(math.isclose(0.1 + 0.2, 0.3))  # True

6.特殊浮点数值

Python 浮点数有几个特殊值:

import math

# 正无穷大
positive_inf = float('inf')
print(positive_inf)        # inf
print(math.isinf(positive_inf))  # True

# 负无穷大  
negative_inf = float('-inf')
print(negative_inf)        # -inf

# 非数字 (Not a Number)
nan_value = float('nan')
print(nan_value)           # nan
print(math.isnan(nan_value))  # True

# 这些值的运算特性
print(positive_inf + 100)  # inf
print(positive_inf * 2)    # inf  
print(positive_inf / positive_inf)  # nan
print(nan_value == nan_value)  # False! (重要)

7.处理浮点数的实用技巧

7.1.四舍五入

number = 3.1415926535

print(round(number))       # 3
print(round(number, 2))    # 3.14
print(round(number, 4))    # 3.1416

# 注意银行家舍入法(四舍六入五成双)
print(round(2.5))   # 2
print(round(3.5))   # 4

7.2.格式化输出

浮点数的格式化输出是指按照指定的格式将浮点数转换为字符串,常用于打印、日志或生成报表等场景。

price = 19.9876

# 1. 使用 f-string(推荐,Python 3.6+)
print(f"价格: {price:.2f}")  # .2f 表示保留两位小数,输出: 价格: 19.99

# 2. 使用百分号格式化
print("价格: %.2f" % price)  # 输出: 价格: 19.99

# 3. 使用 str.format 方法
print("价格: {:.1f}".format(price))  # .1f 表示保留一位小数,输出: 价格: 20.0

# 4. 科学计数法格式化
large_num = 1234567.89
print(f"{large_num:.2e}")  # .2e 表示用科学计数法保留两位小数,输出: 1.23e+06

# 5. 控制宽度和对齐
value = 3.14159
print(f"{value:10.2f}")   # 宽度10,右对齐,保留2位小数,输出: '      3.14'
print(f"{value:<10.2f}")  # 宽度10,左对齐,保留2位小数,输出: '3.14      '

# 6. 千分位分隔符
big_number = 1234567.89
print(f"{big_number:,.2f}")  # 输出: 1,234,567.89

格式化总结

  • f-string 是最简洁、功能最强大的格式化方式
  • %.2f{:.2f} 都可以控制小数位数
  • :e:E 用于科学计数法
  • :, 可以添加千分位分隔符

7.3.精确计算 - 使用 decimal 模块

当需要精确计算时(如金融应用),可以使用 decimal 模块:

from decimal import Decimal

# 使用字符串初始化避免精度问题
a = Decimal('0.1')
b = Decimal('0.2')
c = a + b
print(c)  # 0.3 (精确!)

# 与普通浮点数对比
normal_float = 0.1 + 0.2
print(normal_float)  # 0.30000000000000004

# 设置精度上下文
from decimal import getcontext
getcontext().prec = 6  # 设置6位精度

result = Decimal('1') / Decimal('7')
print(result)  # 0.142857

7.4.分数计算 - 使用 fractions 模块

from fractions import Fraction

# 用分数表示避免浮点误差
a = Fraction(1, 10)  # 1/10
b = Fraction(2, 10)  # 2/10 = 1/5
result = a + b
print(result)        # 3/10
print(float(result)) # 0.3

8.浮点数的内存和性能

  • float类型通常占用24字节内存,int类型小整数约28字节
  • 浮点运算比整数运算稍慢,但差异很小
  • 对于大多数应用,float的内存和性能开销可以接受
import sys
# 查看浮点数占用的内存
float_num = 3.14
int_num = 3

print(f"浮点数占用内存: {sys.getsizeof(float_num)} 字节")  # 通常24字节
print(f"整数占用内存: {sys.getsizeof(int_num)} 字节")      # 通常28字节

# 性能比较(通常浮点运算比整数运算稍慢)
import timeit

float_time = timeit.timeit('x = 3.14 + 2.71', number=1000000)
int_time = timeit.timeit('x = 3 + 2', number=1000000)

print(f"浮点运算时间: {float_time:.6f}秒")
print(f"整数运算时间: {int_time:.6f}秒")

timeit.timeit 是 Python 标准库 timeit 模块中的一个函数,用于测量一段代码执行的时间。它可以帮助我们比较不同代码片段的性能,常用于分析代码的运行效率。例如,可以用它来比较浮点运算和整数运算的速度差异。

9.总结

  1. 基本概念:浮点数用于表示实数,有精度限制
  2. 精度问题:由于二进制表示,某些十进制小数无法精确表示
  3. 特殊值inf(无穷大)、-inf(负无穷大)、nan(非数字)
  4. 比较技巧:不要直接用 == 比较浮点数,使用 math.isclose() 或误差范围
  5. 精确计算:金融等需要精确计算的场景使用 decimal 模块
  6. 格式化输出:使用格式化字符串控制显示精度
  7. 性能考虑:浮点运算通常比整数运算稍慢,但占用内存可能更少
img