跳转至

常量

概述

tiny_constants.h 定义了 TinyMath 中使用的 基本常量和工具宏——从数学常量如 \(\pi\)\(\sqrt{2}\),到位操作辅助宏和定点缩放因子。

所有常量在适当的地方使用了 #ifndef 守卫,确保不会与其他库的定义冲突。


参考

逻辑常量

只在编译器或平台头文件未提供时才定义:

常量 说明
TRUE 1 布尔真
FALSE 0 布尔假
NULL ((void *)0) 空指针常量

为什么用 #ifndef

某些工具链(如 FreeRTOS、ESP-IDF)已经定义了 TRUE/FALSE/NULL#ifndef 守卫可以避免重复定义的警告。


数学常量

常用数学值的浮点常量,使用 f 后缀确保单精度安全:

说明
TINY_PI \(3.14159265358979323846f\) 圆周率 \(\pi\)
TINY_TWO_PI \(6.28318530717958647692f\) \(2\pi\)
TINY_HALF_PI \(1.57079632679489661923f\) \(\pi / 2\)
TINY_E \(2.71828182845904523536f\) 欧拉数 \(e\)
TINY_SQRT2 \(1.41421356237309504880f\) \(\sqrt{2}\)
TINY_INV_SQRT2 \(0.70710678118654752440f\) \(1 / \sqrt{2}\)

角度转换宏:

公式 示例
TINY_DEG2RAD(x) \(x \cdot \dfrac{\pi}{180^\circ}\) TINY_DEG2RAD(180.0f) = \(3.14159\)
TINY_RAD2DEG(x) \(x \cdot \dfrac{180^\circ}{\pi}\) TINY_RAD2DEG(TINY_PI) = \(180.0\)

使用示例

float circumference = 2.0f * TINY_PI * radius;
float sin_45 = sinf(TINY_DEG2RAD(45.0f));  // ≈ 0.707

位操作宏

用于嵌入式寄存器操作和标志位处理的底层位运算:

操作 示例
TINY_BIT(n) 创建位掩码 \((1 \ll n)\) TINY_BIT(3) = 0b00001000
TINY_BIT_SET(x, n) 设置第 \(n\) TINY_BIT_SET(flags, 3)
TINY_BIT_CLEAR(x, n) 清除第 \(n\) TINY_BIT_CLEAR(flags, 3)
TINY_BIT_TOGGLE(x, n) 翻转第 \(n\) TINY_BIT_TOGGLE(flags, 3)
TINY_BIT_CHECK(x, n) 测试第 \(n\) 位(返回 01 TINY_BIT_CHECK(flags, 3)

常用位掩码常量:

掩码 宽度
TINY_MASK_4BIT 0x0F 4 位
TINY_MASK_8BIT 0xFF 8 位
TINY_MASK_16BIT 0xFFFF 16 位
TINY_MASK_32BIT 0xFFFFFFFF 32 位

使用示例

uint8_t reg = 0;

TINY_BIT_SET(reg, 0);   // reg = 0b00000001
TINY_BIT_SET(reg, 7);   // reg = 0b10000001
TINY_BIT_CLEAR(reg, 0); // reg = 0b10000000

if (TINY_BIT_CHECK(reg, 7)) {
    // 第 7 位已设置
}

// 提取低半字节
uint8_t lower = reg & TINY_MASK_4BIT;  // = 0x00

定点缩放因子

对于没有硬件 FPU 的 MCU,定点运算可以比浮点快几个数量级。这些常量提供了标准 Q 格式的缩放因子:

格式
TINY_Q7_SCALE \(2^7 = 128\) Q7(1 字节)
TINY_Q15_SCALE \(2^{15} = 32768\) Q15(2 字节)
TINY_Q31_SCALE \(2^{31} = 2147483648\) Q31(4 字节)

何时使用定点数

ESP32(带硬件 FPU)上,通常不需要定点数。在更简单的 MCU 上或性能关键的内部循环中,Q15 和 Q31 格式可以在没有浮点开销的情况下提供出色的精度。


安全常量

这些常量定义了所有数学子模块中使用的数值安全边界:

用途
TINY_MATH_MIN_DENOMINATOR \(1 \times 10^{-6}\) 除法中允许的最小分母,防止溢出或除零
TINY_MATH_MIN_POSITIVE_INPUT_F32 \(1 \times 10^{-12}\) 诸如 sqrt()log() 操作的最小正输入——避免定义域错误
TINY_MATH_LARGE_VALUE_F32 \(1 \times 10^{38}\) 一个对 IEEE 754 单精度安全的"大数"(最大值 ≈ \(3.4 \times 10^{38}\)),用作哨兵值或类似无穷大的值

源码

/**
 * @file tiny_constants.h
 * @author SHUAIWEN CUI (SHUAIWEN001@e.ntu.edu.sg)
 * @brief This file contains the constants used in the tiny_math middleware.
 * @version 1.0
 * @date 2025-04-15
 * @copyright Copyright (c) 2025
 */

#pragma once

#ifdef __cplusplus
extern "C"
{
#endif

// =======================================
//  Logical Constants
// =======================================
#ifndef TRUE
#define TRUE 1
#endif

#ifndef FALSE
#define FALSE 0
#endif

#ifndef NULL
#define NULL ((void *)0)
#endif

// =======================================
//  Math Constants (float/double safe)
// =======================================
#define TINY_PI 3.14159265358979323846f
#define TINY_TWO_PI 6.28318530717958647692f
#define TINY_HALF_PI 1.57079632679489661923f
#define TINY_E 2.71828182845904523536f
#define TINY_SQRT2 1.41421356237309504880f
#define TINY_INV_SQRT2 0.70710678118654752440f

#define TINY_DEG2RAD(x) ((x) * TINY_PI / 180.0f)
#define TINY_RAD2DEG(x) ((x) * 180.0f / TINY_PI)

// =======================================
//  Bitmask & Bit Manipulation
// =======================================

// Bitwise operations
#define TINY_BIT(n) (1U << (n)) // e.g. TINY_BIT(3) = 0b00001000
#define TINY_BIT_SET(x, n) ((x) |= TINY_BIT(n))
#define TINY_BIT_CLEAR(x, n) ((x) &= ~TINY_BIT(n))
#define TINY_BIT_TOGGLE(x, n) ((x) ^= TINY_BIT(n))
#define TINY_BIT_CHECK(x, n) (((x) >> (n)) & 0x1U)

// Common bit masks
#define TINY_MASK_4BIT 0x0FU
#define TINY_MASK_8BIT 0xFFU
#define TINY_MASK_16BIT 0xFFFFU
#define TINY_MASK_32BIT 0xFFFFFFFFU

// =======================================
//  Fixed-Point Scaling Factors
// =======================================
#define TINY_Q7_SCALE 128          // 2^7
#define TINY_Q15_SCALE 32768       // 2^15
#define TINY_Q31_SCALE 2147483648U // 2^31

// =======================================
//  User-Defined Constants (Optional)
// =======================================
#define TINY_MATH_MIN_DENOMINATOR 1e-6f         // Minimum denominator for safe division
#define TINY_MATH_MIN_POSITIVE_INPUT_F32 1e-12f // Minimum positive input for float operations
#define TINY_MATH_LARGE_VALUE_F32 1e38f         // Large value used to represent infinity-like results (safe for IEEE 754 float, max ~3.4e38)

#ifdef __cplusplus
}
#endif