在我的32位嵌入式C++应用程序中,我需要执行以下计算:
calc(int milliVolts, int ticks) {
return milliVolts * 32767 * 65536 / 1000 / ticks;
}
Run Code Online (Sandbox Code Playgroud)
现在,由于我平台上的int有32位而milliVolts的范围是[-1000:1000],因此该milliVolts * 32767 * 65536部分可能导致整数溢出.为了避免这种情况,我将因子65536分成1024,32并重新排序,如下所示:
calc(int milliVolts, int ticks) {
return milliVolts*32767*32/1000*1024/ticks*2;
}
Run Code Online (Sandbox Code Playgroud)
这样,只要编译器保留乘法和除法的顺序,函数就会正确计算.
Kerninghan和Ritchie在"C编程语言"第2.12节中指出(我没有C++标准的副本):
与大多数语言一样,C不指定运算符操作数的计算顺序.
如果我理解正确,编译器可以自由地将我精心挑选的表达式更改为无法正常工作的表达式.
如何以保证工作的方式编写我的函数?
编辑:下面的几个答案建议使用浮点计算来避免这个问题.这不是一个选项,因为代码在没有浮点运算的CPU上运行.此外,计算是在我的应用程序的硬实时部分,因此使用模拟浮点的速度惩罚太大.
结论:在Merdad的回答和Matt McNabb的评论的帮助下,我设法找到K&R的相关部分,A7部分,其中说:
运算符的优先级和关联性是完全指定的,但是表达式的求值顺序在某些例外情况下是未定义的,即使子表达式涉及副作用.也就是说,除非运算符的定义保证以特定顺序评估其操作数,否则实现可以按任何顺序自由地评估操作数,甚至可以交错评估.但是,每个运算符以与其出现的表达式的解析兼容的方式组合其操作数生成的值.此规则撤销了以前使用运算具有交换和关联的运算符重新排序表达式的自由,但可能无法进行计算关联.该更改仅影响其精度限制附近的浮点计算,以及可能出现溢出的情况.
因此Merdad是对的:没有什么可担心的.
我有一个脚本从jenkins工作中提取工件并将其安装在我们的硬件测试系统上.现在,今天我需要降级到相当旧的版本.不幸的是,jenkins API只返回最后几个版本.
我使用jenkinsapi python API.它失败如下:
/usr/local/lib/python2.7/dist-packages/jenkinsapi-0.1.6-py2.7.egg/jenkinsapi/job.pyc in get_build(self, buildnumber)
177 def get_build( self, buildnumber ):
178 assert type(buildnumber) == int
--> 179 url = self.get_build_dict()[ buildnumber ]
180 return Build( url, buildnumber, job=self )
181
Run Code Online (Sandbox Code Playgroud)
python API命中了url http://jenkins/job/job-name/api/python/.如果我自己这样做,那么我会收到以下回复:
{"actions":[{},{},{},{},{},{},{}],
"description":"text",
"displayName":"job-name",
"displayNameOrNull":None,
"name":"job-name",
"url":"http://jenkins/job/job-name/",
"buildable":True,
"builds":[
{"number":437,"url":"http://jenkins/job/job-name/437/"},
{"number":436,"url":"http://jenkins/job/job-name/436/"},
{"number":435,"url":"http://jenkins/job/job-name/435/"},
{"number":434,"url":"http://jenkins/job/job-name/434/"},
{"number":433,"url":"http://jenkins/job/job-name/433/"},
{"number":432,"url":"http://jenkins/job/job-name/432/"},
{"number":431,"url":"http://jenkins/job/job-name/431/"},
{"number":430,"url":"http://jenkins/job/job-name/430/"},
{"number":429,"url":"http://jenkins/job/job-name/429/"},
{"number":428,"url":"http://jenkins/job/job-name/428/"},
{"number":427,"url":"http://jenkins/job/job-name/427/"},
{"number":426,"url":"http://jenkins/job/job-name/426/"},
{"number":425,"url":"http://jenkins/job/job-name/425/"},
{"number":424,"url":"http://jenkins/job/job-name/424/"},
{"number":423,"url":"http://jenkins/job/job-name/423/"}],
"color":"yellow_anime",
"firstBuild": {"number":311,"url":"http://jenkins/job/job-name/311/"},
"healthReport":[
{"description":"Test Result: 0 tests failing out of a total of 3 tests.","iconUrl":"health-80plus.png","score":100},
{"description":"Build stability: …Run Code Online (Sandbox Code Playgroud) 注意:此问题已移至serverfault.com.
我想帮助找到我的应用程序中降低数据传输速率的原因.
我有12个嵌入式系统和一个Linux服务器.嵌入式系统通过交换机在以太网链路上通过TCP向服务器发送数据.以下是通过Wireshark捕获来自一块板的流量的TCP StreamGraph.

如您所见,数据传输速度约为5.8MBit/s,最高可达0.25秒.这跟我所期望的嵌入式系统一样快.在此之后,在传输中插入延迟.以下显示了图表的特写:

底部标有ACK的楼梯形曲线显示服务器在任何给定时间已确认了多少数据.标记为RWIN的相应曲线显示数据带上的缓冲区中有多少空间.标记为SENT DATA的较小垂直段是发送的实际包.
在A点,服务器以尽可能快的速度确认数据,但是在23ms的持续时间内,服务器不会发送任何消息.允许嵌入式系统在不等待ACK的情况下发送到RWIN,但它不会这样做,因为它需要保持发送的数据,直到它们被激活(如果需要重新发送)并且发送缓冲区空间是有限.
然后,在B点,所有接收的数据立即被确认,正常的acking和发送在另一个暂停发生之前恢复2.5ms.
Wireshark捕获是由另一台PC完成的,该PC连接到交换机上的一个端口,该端口设置为镜像嵌入式系统所连接的端口上发送和接收的所有数据.
Linux服务器运行Java应用程序,该应用程序处理数据并将其存储在磁盘上.它没有显示出最大化CPU的迹象.操作系统是Ubuntu Server 12.04,具有默认网络设置.
我可以看到,我可能会从嵌入式系统中分配更多的发送缓冲区空间中获益,以匹配Linux服务器中的接收窗口空间量,但这似乎不是限制因素.
我的问题是: