C 或 C++ 中是不是有一个函数可以对整数进行“饱和”

Posted

技术标签:

【中文标题】C 或 C++ 中是不是有一个函数可以对整数进行“饱和”【英文标题】:is there a function in C or C++ to do "saturation" on an integerC 或 C++ 中是否有一个函数可以对整数进行“饱和” 【发布时间】:2011-05-21 04:57:05 【问题描述】:

我正在做一些 3D 图形,我有一片开阔的海洋。对于这个海洋,我有一个矩阵,表示特定矩形海域的海况(即波高)。海洋的其余部分是平坦的。我的问题是,我的受控海(有波浪)位于开阔平坦的大海中间,网格边缘的不连续性会导致一些不良伪影。我只为一小部分而不是整个海洋产生波浪的原因是因为我的噪声函数在整个海洋上计算起来非常昂贵(而且我知道最简单的解决方案是使用更便宜的噪声函数,比如单纯形噪声,但这不是一个选项)。

话虽如此,我的问题确实很简单。如果说我有一个大小为 100x40 的网格(又名矩阵又名 2d 数组),并且我想找到位置 120x33 的值,我只想取最近的邻居,即 100x33。因此,对于位于给定范围之外的任何数字,我希望该数字饱和以位于给定范围内。 C 或 C++ 中是否有执行此操作的函数?

编辑:位置参数是浮点类型

我知道我可以用一些简单的 if 语句来做到这一点,但它似乎是标准库会包含的东西。

【问题讨论】:

有SSE指令支持饱和。 这是否需要在汇编中编码?我也可以指定范围还是仅饱和到原始数据类型的范围? 我认为任何现代机器都应该能够毫无问题地完成整个海洋。我的软件 (orcina.com/SoftwareProducts/OrcaFlex) 这样做了,尽管它在本质上有所不同,因为它试图真实地模拟物理场。 @david:他们可以而且他们确实可以,但是我从一些 MATLAB 代码通过网络获取我的海洋频谱,这些 ATM 没有编译,因此运行速度比原生 C 慢 100 倍,并且在 MATLAB 中,这对于整个海洋来说更难实时完成。如果您对如何在 MATLAB 中使用 38 个叠加的 sin 函数对具有约 1k 数据点的网格实时快速(200Hz)有任何想法,我很想听听。 @codenoob 最明显的技巧是仅评估 t0 处的三角函数,然后对 t1、t2 等使用加法公式。这样你只需要 FP 乘法/加法而不用触发。 【参考方案1】:

现在有了std::clamp 的形式。而且我只迟到了七年:)

【讨论】:

【参考方案2】:
template<typename T>
T saturate(T val, T min, T max) 
    return std::min(std::max(val, min), max);

【讨论】:

如果 val 已经遭受基本类型 T 的下溢/溢出,则将无法工作。【参考方案3】:

ISO/IEC JTC1 SC22 WG14 N1169(编程语言 - C - 支持嵌入式处理器的扩展)为饱和数据类型指定了 _Sat 类型限定符。我从未尝试在任何编译器中使用它,但它包含在GCC 4.x documentation 中。

VC++ 2003 及更高版本支持MMX intrinsics,允许饱和算术。

【讨论】:

MMX 内部链接已失效 @EricJohnson :这应该不足为奇,因为该帖子已超过 6 年。我不打算在发布的 2000 多个答案中维护链接!提供了搜索 MSDN 或 Google 所需的关键术语。 VS2010 here 和 VS2015 here 的存档文档 - 尽管不再很好地分类。我也想在 2017 年。 _Sat _Accum / _Sat _Fract x86、ARM、ARM64 或 AVR 的 gcc 不支持定点类型。 godbolt.org/z/RrMa8l :( 我没有在 Godbolt 上尝试任何其他 ISA,但我认为 MIPS / PowerPC / RISC-V 也不支持 gcc。gcc.gnu.org/onlinedocs/gcc/Fixed-Point.html 没有说明它们支持哪些目标。跨度> 哦,clang 支持他们-ffixed-point!但是对于 x86,它只是在没有实际饱和的情况下进行加法,只是换行。 godbolt.org/z/akWV0N。但是对于 RISC-V,有很多指令可以做……某事(?)【参考方案4】:

最小和最大没有?

x = std::min(100,x);
y = std::min(40,y);

【讨论】:

默认情况下是根据条件运算符 if 来实现的。【参考方案5】:

或者如果你喜欢复杂的定义!

#define DERIVE_MAX (100)

//Saturate X at +/-DERIVE_MAX
#define SAT(x) ( ((x) > DERIVE_MAX) ? DERIVE_MAX : ( (-(x) > DERIVE_MAX) ? (-DERIVE_MAX) : (x) ) )

【讨论】:

以上是关于C 或 C++ 中是不是有一个函数可以对整数进行“饱和”的主要内容,如果未能解决你的问题,请参考以下文章

这种使用 C++ 异常是不是合理

C 或 C++ 链接器中是不是有任何类型检查?

让函数返回字符串而不是整数是否很糟糕? (C++)

main函数可否进行递归调用

c++ sort 函数能对类或者结构体进行排序吗

如何在 C++ 或 C 中浏览文件夹?