我正在为学校制作一个简单的视频游戏程序,我已经创建了一种方法,如果调用该方法,玩家将获得15个健康点.我必须保持最高100的健康状态,并且我现在有限的编程能力,我正在做这样的事情.
public void getHealed(){
if(health <= 85)
health += 15;
else if(health == 86)
health += 14;
else if(health == 87)
health += 13;
}// this would continue so that I would never go over 100
Run Code Online (Sandbox Code Playgroud)
我理解我的语法并不完美,但我的问题是,这可能是一个更好的方法,因为我还必须对损伤点做类似的事情,而不是低于0.
这称为饱和算术.
想象一下,我有两个无符号字节b和x.我需要计算bsubas b - x和baddas b + x.但是,我不希望在这些操作期间发生下溢/溢出.例如(伪代码):
b = 3; x = 5;
bsub = b - x; // bsub must be 0, not 254
Run Code Online (Sandbox Code Playgroud)
和
b = 250; x = 10;
badd = b + x; // badd must be 255, not 4
Run Code Online (Sandbox Code Playgroud)
显而易见的方法包括分支:
bsub = b - min(b, x);
badd = b + min(255 - b, x);
Run Code Online (Sandbox Code Playgroud)
我只是想知道是否有更好的方法来做到这一点,即通过一些hacky位操作?
在C中编写饱和加法的最佳(最干净,最有效)方法是什么?
函数或宏应添加两个无符号输入(需要16位和32位版本),如果总和溢出,则返回所有位 - 一(0xFFFF或0xFFFFFFFF).
目标是x86和ARM使用gcc(4.1.2)和Visual Studio(仅用于模拟,因此可以使用后备实现).
c algorithm performance signal-processing saturation-arithmetic
我正在寻找一些用于签名饱和64位加法的C代码,它使用gcc优化器编译为高效的X86-64代码.便携式代码是理想的,尽管如果需要可以使用asm解决方案.
static const int64 kint64max = 0x7fffffffffffffffll;
static const int64 kint64min = 0x8000000000000000ll;
int64 signed_saturated_add(int64 x, int64 y) {
bool x_is_negative = (x & kint64min) != 0;
bool y_is_negative = (y & kint64min) != 0;
int64 sum = x+y;
bool sum_is_negative = (sum & kint64min) != 0;
if (x_is_negative != y_is_negative) return sum; // can't overflow
if (x_is_negative && !sum_is_negative) return kint64min;
if (!x_is_negative && sum_is_negative) return kint64max;
return sum;
}
Run Code Online (Sandbox Code Playgroud)
写入的函数产生具有多个分支的相当长的汇编输出.有关优化的提示吗?看起来它应该只用一个带有一些CMOV指令的ADD来实现,但我对这些东西有点生疏.
我正在完成一项任务,我无法弄清楚如何实现这一点.我必须创建一个函数sadd(int x,int y),它返回添加在一起的数字,除非它溢出(然后只返回max possible int).我已经能够提出一些涉及强制转换和条件语句的解决方案,但解决方案中不允许这些解决方案.只有经营者〜!^ + << >>&和|.
有符号 2 的补码 32 位整数的问题:
\n\n\n\n
satMul2- 乘以 2,饱和Tmin或Tmax溢出。
\n示例:satMul2(0x30000000) = 0x60000000
\n\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0satMul2(0x40000000) = 0x7FFFFFFF(饱和到TMax)
\n\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0\xc2\xa0satMul2(0x60000000) = 0x80000000(饱和到TMin)
\n合法操作:!~&^|+<<>>
\n最大操作:20
\n评级:3
我想实现一个类似的功能
\nif (a) return b;\nelse return c;\nRun Code Online (Sandbox Code Playgroud)\n这是我的解决方案(10 次操作):
\nint satMul2(int x) {\n int rval = x << 1;\n int sign = rval ^ x;\n int minn = 1 << 31;\n …Run Code Online (Sandbox Code Playgroud) c bit-manipulation bitwise-operators micro-optimization saturation-arithmetic
我一直在看MMX / SSE,我想知道。对于无符号字节和字(而非双字),有打包,饱和减法的说明。
有什么方法可以做我想要的,如果没有,为什么没有呢?
是否有一种优雅的方法可以将较大的数据类型转换为较小的数据类型而不导致结果溢出?
例如,转换260为uint8_t应该导致255而不是4.
一个可能的解决方案是:
#include <limits.h>
#include <stdint.h>
inline static uint8_t convert_I32ToU8(int32_t i32)
{
if(i32 < 0) return 0;
if(i32 > UINT8_MAX) return UINT8_MAX;
return (uint8_t)i32;
}
Run Code Online (Sandbox Code Playgroud)
虽然这个解决方案有效,但我想知道是否有更好的方法(无需创建大量转换函数)。
解决方案应该是 C 语言(可选 GCC 编译器扩展)。
在 Rust 中寻找饱和函数。
这里我称之为fit_to_range(range)。
let input:i64= something;
let saturated:64= input.fit_to_range(7..=4000);
assert!((7..=4000).contains(saturated));
Run Code Online (Sandbox Code Playgroud) 我最近面临一个给定的问题:
\n\n\n向量中有8个元素,每个元素都用int8_t表示。
\n在 x86_64 中实现一个算法,将两个向量(uint64_t 类型)相加。
\n添加元素时应考虑饱和算术。
\n例如:
\n80 + 60 = 127
\n(\xe2\x88\x9240) + (\xe2\x88\x92100) = \xe2\x88\x92128
\n
最大的挑战是施加的限制:
\n我想不出任何符合这些限制的解决方案。\n有人能给我一些提示吗?欢迎使用 C 语言的示例。
\n我只能使用“标准”、传输、算术、逻辑指令和标准寄存器:
\n