数学 ========= 该部分主要完成数学变换功能,具体包括数字映射、数字约束、数学运算、取整、随机、三角函数。 .. image:: images/03Mathematics/math.png 1.数字常量 ----------- .. image:: images/03Mathematics/number.png .. code-block:: c :linenos: 0; 1.1 描述 ++++++++++++++ 数字常量包括 整数常量和浮点常量。 .. Attention:: 整数常量是直接在程序中使用的数字,如123。默认情况下,这些数字被视为int类型。通常情况下,整数常量默认为十进制,但可以加上特殊前缀表示为其他进制。如:B0111,表示二进制;0173,表示八进制;0x7B,表示十六进制。 浮点常量也可以直接中程序中使用,如12.3。默认情况下,这些数字被视为float类型。也可以使用科学计数法表示浮点数。如:2.34E5代表2.34 * 10^5,其实际值为234000;67E-12代表67.0 * 10^-12,其实际值为0.000000000067。 数学运算 ----------- .. image:: images/03Mathematics/math_operation.png .. code-block:: c ;linenos: 1 + 1; 描述 ++++++++++++++ 数学运算中包括加、减、乘、除、取模、幂运算。 这些运算将会返回两个操作数的和,差,乘积,商,取模、幂。 2.2 参数 ++++++++++++++ 常量或变量 2.3 返回值 ++++++++++++++ 两个操作数的和,差,乘积,商,取模,幂。 .. Attention:: - 这些运算是根据操作数的数据类型来计算的,比如 9和4都是int类型,所以9/4结果是2。 - 如果想要两个整数相除得到小数,就需要将整数转换成小数。如9.0/2.0=4.5 。 - 这也就代表如果运算结果比数据类型所能容纳的范围要大的话,就会出现溢出。例如. 1加上一个整数 int类型 32,767 结果变成-32,768。 - 如果操作数是不同类型的,结果是“更大”的那种数据类型。如果操作数中的其中一个是 float类型或者double类型, 就变成了浮点数运算。 3.位运算 ----------- .. image:: images/03Mathematics/math_bit_operation.png .. code-block:: c :linenos: (0&0); 3.1 描述 ++++++++++++++ 按位操作符对变量进行位级别的计算。 3.2按位与(&) ++++++++++++++ 按位与操作符一个&符,用在两个整型变量之间。按位与运算符对两侧的变量的每一位都进行运算。 3.2.1 描述 ********* 如果两个运算元都是1,则结果为1,否则输出0。 3.2.2 范例 ********* 在Arduino中,int类型为16位,所以在两个int表达式之间使用&会进行16个并行按位与计算。 .. image:: images/03Mathematics/and_example.png .. code-block:: c :linenos: volatile int a; volatile int b; volatile int c; void setup(){ a = 92; b = 101; c = (a&b); } void loop(){ } 3.3 按位或(|) ++++++++++++++ 按位或操作符是|。 和&操作符类似,|操作符对两个变量的为一位都进行运算,只是运算规则不同。 3.3.1 描述 ********* 只要两个位有一个为1则结果为1,否则为0。 如:0011|0101=0111 3.3.2 范例 ********* 在Arduino中,int类型为16位,所以在两个int表达式之间使用&会进行16个并行按位或计算。 .. image:: images/03Mathematics/or_example.png .. code-block:: c :linenos: volatile int a; volatile int b; volatile int c; void setup(){ a = 92; b = 101; c = (a|b); } void loop(){ } 3.4 按位异或(^) ++++++++++++++ 按位异或是一个不常见的操作符,也叫做XOR(通常读作”eks-or“)。 按位异或操作符用 ^ 表示。 3.4.1 描述 ********* 按位异或是如果两个位值相同则结果为0,否则为1。 如:0011^0101=0110 3.5 左移位运算(<<) ++++++++++++++ 左移位运算可使左运算元中的某些位移动右运算元中指定的位数。 3.5.1 范例 ********* .. image:: images/03Mathematics/leftShift_example_1.png .. code-block:: c :linenos: volatile int a; volatile int b; void setup(){ a = 5; b = (a<<3); } void loop(){ } .. image:: images/03Mathematics/leftShift_example_2.png .. code-block:: c :linenos: volatile int a; volatile int b; void setup(){ a = 5; b = (a<<14); } void loop(){ } 如果你确定位移不会引起数据溢出,你可以简单的把左移运算当做对左运算元进行2的右运算元次方的操作。 3.6 右移位运算(>>) ++++++++++++++ 右移位运算与左移位运算类似。 4.三角函数及其他 ----------- .. image:: images/03Mathematics/math_trig.png 4.1 sin函数 ++++++++++++++ 计算角度的正弦(弧度)。其结果在-1和1之间。 4.1.1 参数 ****** 弧度制的角度(float) 4.1.2 返回值 ****** 角度的正弦值(double) 4.2 cos函数 ++++++++++++++ 计算一个角度的余弦值(用弧度表示)。返回值在 -1 和 1 之间。 4.2.1 参数 ********* 弧度制的角度(float) 4.2.2 返回值 ********* 角度的正弦值(double) 4.2.3 范例 ********* 绘制SIN-COS的函数图像,程序上传后,打开串口监视器,并切换到绘图模式 .. image:: images/03Mathematics/sin_cos_example.png .. code-block:: c :linenos: void setup(){ Serial.begin(9600); } void loop(){ for (int i = 0; i <= 360; i = i + (1)) { Serial.print((sin(i / 180.0 * 3.14159) * 256 + 512)); Serial.print(","); Serial.println((cos(i / 180.0 * 3.14159) * 256 + 512)); delay(200); } } 4.3 tan函数 ++++++++++++++ 计算角度的正切(弧度)。结果在负无穷大和无穷大之间。 4.3.1 参数 ********* 弧度制的角度(float) 4.3.2 返回值 ********* 角度的正切值 4.4 asin函数 ++++++++++++++ 反正弦函数为正弦函数sin的反函数。 4.4.1 参数 ********* [-1,1] 4.4.2 返回值 ********* [-π/2,π/2] 4.5 acos函数 ++++++++++++++ 反余弦函数为余弦函数cos的反函数。 4.5.1 参数 ********* [-1,1] 4.5.2 返回值 ********* [0,π] 4.6 atan函数 ++++++++++++++ 反正切函数为正切函数tan的反函数。 4.6.1 参数 ********* [-∞,∞] 4.6.2 返回值 ********* (-π/2,π/2) 5.数学运算2 ----------- .. image:: images/03Mathematics/round.png 5.1 取整(四舍五入)(round) ++++++++++++++ 返回给定值的四舍五入取整值。如round(4.1)=4;round(5.6)=6。 5.1.1 参数 ********* 数值或变量。 5.1.2 返回值 ********* 给定值的四舍五入取整值 5.2 取整(取上限)(ceil) ++++++++++++++ 返回给定值的下一个整数,如果输入的本身就是整数,则返回自身。如ceil(4.1)=5;ceil(5.6)=6,ceil(7)=7。 5.2.1 参数 ********* 数值或变量。 5.2.2 返回值 ********* 给定值的下一个整数或自身。 5.3 取整(取下限)(floor) ++++++++++++++ 返回给定值的前一个整数,如果输入的本身就是整数,则返回自身。如 floor(4.1)=4;floor(5.6)=5,floor(7)=7。 5.3.1 参数 ********* 数值或变量。 5.3.2 返回值 ********* 给定值的前一个整数或自身。 5.4 取绝对值(abs) ++++++++++++++ 返回给定值的绝对值。如abs(4.1)=4;abs(-5.6)=5,abs(7)=7。 5.4.1 参数 ********* 数值或变量。 5.4.2 返回值 ********* 给定值的绝对值。 5.5 平方(sq) ++++++++++++++ 返回给定值的平方。如 sq(4)=16;sq(-5)=25,sq(7)=49。 5.5.1 参数 ********* 数值或变量。 5.5.2 返回值 ********* 给定值的平方。 5.6 平方根(sqrt) ++++++++++++++ 返回给定值的正平方根。如 sqrt(4)=2;sqrt(25)=5。 5.6.1 参数 ********* 数值或变量。 5.6.2 返回值 ********* 给定值的正平方根。 6.取最大(小)值(min/max) ----------- .. image:: images/03Mathematics/max.png 描述 ++++++++++++++ 返回两个数值或变量中最大或最小值。 参数 ++++++++++++++ 数值或者变量 返回值 ++++++++++++++ 最大值或最小值 7.初始化随机数(randomseed) ----------- .. image:: images/03Mathematics/randomseed.png 描述 ++++++++++++++ 使用randomSeed()初始化伪随机数生成器,使生成器在随机序列中的任意点开始。 使用随机数之前,需要先使用初始化随机数模块。 8.随机数(random) ----------- .. image:: images/03Mathematics/random.png 描述 ++++++++++++++ 使用随机数模块可以产生一个给定范围之间的随机数。 参数 ++++++++++++++ min - 随机数的最小值,随机数将包含此值。 (此参数可选) max - 随机数的最大值,随机数不包含此值。 返回 ++++++++++++++ min和max-1之间的随机数( 数据类型为long ) 范例 ++++++++++++++ 随机数不包括最大数,如 1—7 随机数只有 1、2、3、4、5、6。 .. image:: images/03Mathematics/random_example.png .. code-block:: c :linenos: void setup(){ Serial.begin(9600); randomSeed(997); } void loop(){ Serial.println((random(1, 100))); delay(100); } 9.约束(constrain) ----------- .. image:: images/03Mathematics/constrain.png 描述 ++++++++++++++ 约束是将数值限制在最小值与最大值之间,所有小于最小值的数值被赋值为最小值,同理,所有大于最大值的数被赋值为最大值。 参数 ++++++++++++++ x:要被约束的数字,所有的数据类型适用。 a:该范围的最小值,所有的数据类型适用。 b:该范围的最大值,所有的数据类型适用。 返回值 ++++++++++++++ x:如果 x是介于 a 和 b之间 a:如果 x小于a b:如果 x大于b 范例 ++++++++++++++ A0连接电位器,将看到LED亮灭随电位器的旋转约束在0-255之间不同的亮度 .. image:: images/03Mathematics/constrain_example.png .. code-block:: c :linenos: void setup(){ } void loop(){ analogWrite(11,(constrain(((long) (analogRead(A0)) % (long) (3)) * 50, 0, 255))); } 10.映射(map) ----------- .. image:: images/03Mathematics/map.png 描述 ++++++++++++++ 约束是将数值限制在最小值与最大值之间,所有小于最小值的数值被赋值为最小值,同理,所有大于最大值的数被赋值为最大值。 参数 ++++++++++++++ x:要被约束的数字,所有的数据类型适用。 a:该范围的最小值,所有的数据类型适用。 b:该范围的最大值,所有的数据类型适用。 返回值 ++++++++++++++ x:如果 x是介于 a 和 b之间 a:如果 x小于a b:如果 x大于b 范例 ++++++++++++++ A0接电位器,串口输出20-180区间的数值 .. image:: images/03Mathematics/map_example.png .. code-block:: c :linenos: void setup(){ Serial.begin(9600); } void loop(){ Serial.println((map(analogRead(A0), 0, 1023, 20, 180))); delay(500); }