大佬教程收集整理的这篇文章主要介绍了c – 如何“混合”两个值而不溢出?,大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
// Return a blended value of x and y: // blend(100,200,1,1) -> 150 // blend(100,2,1) -> 133 uint8_t blend(uint8_t x,uint8_t y,uint8_t parts_x,uint8_t parts_y) { uint32_t big_parts_x = parts_x; uint32_t big_parts_y = parts_y; return (uint8_t) ((big_parts_x * x + big_parts_y * y) / (big_parts_x + big_parts_y)); }
有没有办法接近适当的返回值而不需要任何大于uint8_t的分配?您可以通过执行两个分区轻松地将其分解(减少四舍五入)为两个uint16_t的添加.你能用uint8_t做到吗?
C standard第6.3.1.1p2节规定:
第E.1节还规定int必须能够支持至少在-32767到32767范围内的值,而unsigned int必须支持至少在0到65535范围内的值.
由于uint8_t的排名低于int,因此当前者成为大多数运算符的主题时,前者将始终被提升为后者,包括,–,*和/.
uint8_t blend(uint8_t x,uint8_t parts_y) { return ((1u*parts_x*X) / (parts_x + parts_y)) + ((1u*parts_y*y) / (parts_x + parts_y)); }
表达式parts_x * x和parts_y * y的最大值为65025.这对于16位int而言太大而不是16位无符号int,因此每个乘以1u以强制将值转换为unsigned int按照6.3.1.8节中规定的通常算术转换:
另请注意,我们将每个部分分别除以总和.如果我们在分割之前首先添加两个部分,则分子可能超过65535.通过首先进行除法,这会使每个子表达式回到uint8_t的范围内.然后我们可以添加两个部分,它们将再次位于uint8_t的范围内.
因此,上述表达式保证在符合C标准的编译器上返回正确的精确答案.
以上是大佬教程为你收集整理的c – 如何“混合”两个值而不溢出?全部内容,希望文章能够帮你解决c – 如何“混合”两个值而不溢出?所遇到的程序开发问题。
如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。
本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。