标签: saturation-arithmetic

如何在不超过最大值的情况下增加变量?

我正在为学校制作一个简单的视频游戏程序,我已经创建了一种方法,如果调用该方法,玩家将获得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.

这称为饱和算术.

java if-statement switch-statement saturation-arithmetic

89
推荐指数
6
解决办法
1万
查看次数

减去/添加值而不会出现溢出或下溢

想象一下,我有两个无符号字节bx.我需要计算bsubas b - xbaddas 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 c++ optimization bit-manipulation saturation-arithmetic

82
推荐指数
4
解决办法
1万
查看次数

如何在C中进行饱和添加?

在C中编写饱和加法的最佳(最干净,最有效)方法是什么?

函数或宏应添加两个无符号输入(需要16位和32位版本),如果总和溢出,则返回所有位 - 一(0xFFFF或0xFFFFFFFF).

目标是x86和ARM使用gcc(4.1.2)和Visual Studio(仅用于模拟,因此可以使用后备实现).

c algorithm performance signal-processing saturation-arithmetic

40
推荐指数
7
解决办法
3万
查看次数

签名饱和添加64位整数?

我正在寻找一些用于签名饱和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来实现,但我对这些东西有点生疏.

c optimization x86-64 addition saturation-arithmetic

11
推荐指数
4
解决办法
1919
查看次数

C(HW)中的逐位饱和加法

我正在完成一项任务,我无法弄清楚如何实现这一点.我必须创建一个函数sadd(int x,int y),它返回添加在一起的数字,除非它溢出(然后只返回max possible int).我已经能够提出一些涉及强制转换和条件语句的解决方案,但解决方案中不允许这些解决方案.只有经营者〜!^ + << >>&和|.

c bit-manipulation addition saturation-arithmetic

7
推荐指数
1
解决办法
6319
查看次数

C 中 6 次运算中的带符号饱和乘以 2?

有符号 2 的补码 32 位整数的问题:

\n
\n

satMul2- 乘以 2,饱和TminTmax溢出。
\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\xa0 satMul2(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\xa0 satMul2(0x60000000) = 0x80000000(饱和到TMin)
\n合法操作:! ~ & ^ | + << >>
\n最大操作:20
\n评级:3

\n
\n

我想实现一个类似的功能

\n
if (a) return b;\nelse return c;\n
Run Code Online (Sandbox Code Playgroud)\n

这是我的解决方案(10 次操作):

\n
int 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

6
推荐指数
1
解决办法
571
查看次数

有没有办法使用MMX / SSE减去x86上饱和的压缩无符号双字?

我一直在看MMX / SSE,我想知道。对于无符号字节和字(而非双字),有打包,饱和减法的说明。

有什么方法可以做我想要的,如果没有,为什么没有呢?

x86 assembly sse mmx saturation-arithmetic

5
推荐指数
1
解决办法
136
查看次数

有范围限制的铸造类型

是否有一种优雅的方法可以将较大的数据类型转换为较小的数据类型而不导致结果溢出?

例如,转换260uint8_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 编译器扩展)。

c casting data-conversion clamp saturation-arithmetic

5
推荐指数
1
解决办法
630
查看次数

你知道饱和函数吗?使数字适合给定范围?

在 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)

range rust saturation-arithmetic

0
推荐指数
1
解决办法
337
查看次数

为每个 int8_t 元素添加两个具有饱和度的向量(uint64_t 类型)

我最近面临一个给定的问题:

\n
\n

向量中有8个元素,每个元素都用int8_t表示。

\n

在 x86_64 中实现一个算法,将两个向量(uint64_t 类型)相加。

\n

添加元素时应考虑饱和算术。

\n

例如:

\n

80 + 60 = 127

\n

(\xe2\x88\x9240) + (\xe2\x88\x92100) = \xe2\x88\x92128

\n
\n

最大的挑战是施加的限制:

\n
    \n
  • 除ret外无条件指令;没有跳跃、cmove、set 等。
  • \n
  • 该解不能长于 48 条指令(存在短于 37 条指令的解)
  • \n
\n

我想不出任何符合这些限制的解决方案。\n有人能给我一些提示吗?欢迎使用 C 语言的示例。

\n

我只能使用“标准”、传输、算术、逻辑指令和标准寄存器:

\n
    \n
  • mov cbw/cwde/cdqe cwd/cdq/cqo movzx movsx
  • \n
  • 添加 sub imul mul idiv div inc dec neg
  • \n
  • 和或异或非 sar sarx shr shrx shl shlx ror rol
  • \n
  • 雷雷
  • \n
\n

assembly bit-manipulation x86-64 saturation-arithmetic swar

0
推荐指数
1
解决办法
270
查看次数