我刚从在线教程和资源中学习OpenMP.我想使用parallel for循环对矩阵(与其自身相乘)进行平方.在IBM编译器文档中,我发现要求"迭代变量必须是signed整数".在GCC实施中也是如此吗?是否在OpenMP标准中指定?如果是这样,这个要求是否有原因?
(这并不重要,因为预期的尺寸远小于INT_MAX,但它确实花了我一些演员阵容.)
出于各种实现原因,我已经定义了以下枚举:
typedef enum HBSnakeMovementDirection
{
HBSnakeMovementDirectionUp = 1,
HBSnakeMovementDirectionDown = -1,
HBSnakeMovementDirectionRight = 2,
HBSnakeMovementDirectionLeft = -2
}
HBSnakeMovementDirection;
Run Code Online (Sandbox Code Playgroud)
但是,如果我尝试使用HBSnakeMovementDirectionRight,我会收到以下警告:
Implicit conversion changes signedness: 'int' to 'HBSnakeMovementDirection'
任何其他枚举值都没有问题.这有什么问题?我认为这可能与混合负面和正面枚举值有关,但我无法找到任何关于此的确定性.
(我能够提出所有积极的枚举值,让我可以解决这个问题,但它仍然困扰我,所以我想我会问它.)
我应该说,就像我的所有项目一样,我几乎发出了所有警告 - 因此,-Wconversion投诉 - 并将其视为错误.(我喜欢在编译时尽可能严格.)我正在使用LLVM 1.6.
更新1:HBSnakeMovementDirectionRight在前面的警告中逐字地使用结果:
HBSnakeMovementDirection movementDirectionRight = HBSnakeMovementDirectionRight;
Run Code Online (Sandbox Code Playgroud)
我必须施展HBSnakeMovementDirectionRight才能HBSnakeMovementDirection使警告沉默.
更新2:根据要求,这是在我的机器上发出的整个构建命令:
更新3:这是我正在GitHub上托管的确切项目:
https://github.com/LucasTizma/Hebi
具体来说,以下树:
https://github.com/LucasTizma/Hebi/tree/89262e2e53881584daf029e3dd5f1e99dfbd6f96
我正在创建一个PackedUnsigned1616类,它在一个int中存储两个unsigned short,以及一个PackedSigned1616类,它在一个int中存储两个带符号的short.我已经阅读了按位运算,但我仍然对如何处理有符号和无符号以及大于或小于short的范围(它们作为两个整数传入)的值感到困惑.这是我到目前为止所得到的:
public final class PackedUnsigned1616 {
public final int field;
private static final int RIGHT = (2 << 15) - 1;
private static final int LEFT = ((2 << 31) - 1) ^ RIGHT;
public PackedUnsigned1616(int left, int right) {
field = (left << 15) | (right & RIGHT);
}
public int getLeft() {
return field >> 15;
}
public int getRight() {
return field & RIGHT;
}
Run Code Online (Sandbox Code Playgroud)
}
整个概念让我很困惑,所以如果你能对它有所了解,那将会有很大的帮助.
我正在尝试计算滚动平均值,并试图获得并优化一点,我简化了计算,因此只有一个除法.当值减小时,存在当前值降低到小于平均值的点.此时平均跳跃.我想这是因为除法是无符号的,我的分子符号位被解释为一个大的无符号数.我只是不确定我需要在哪里投贴无符号以确保此问题不再出现.
unsigned int AverageUsage;
unsigned int TotalUsage;
unsigned int incCount;
AverageUsage = (TotalUsage - AverageUsage)/++incCount + AverageUsage;
Run Code Online (Sandbox Code Playgroud)
AverageUsage将始终为正,但当TotalUsage低于AverageUsage时,我不确定该部门会有什么期望
AverageUsage = (signed int)(TotalUsage - AverageUsage)/++incCount + AverageUsage;
Run Code Online (Sandbox Code Playgroud)
将分子设置为已签名,但我不确定如何进行除法.
AverageUsage = (signed int)((signed int)(TotalUsage - AverageUsage)/++incCount) + AverageUsage;
Run Code Online (Sandbox Code Playgroud)
应该工作(我可以保证这个完整操作的结果永远不会是负面的),但我担心incCount达到"看起来"负面的值的情况.
是否有一个简单的解决方案,希望:
谢谢!
#include <stdio.h>
int arr[] = {1,2,3,4,5,6,7,8};
#define SIZE (sizeof(arr)/sizeof(int))
int main()
{
printf("SIZE = %d\n", SIZE);
if ((-1) < SIZE)
printf("less");
else
printf("more");
}
Run Code Online (Sandbox Code Playgroud)
编译后的输出gcc是"more".为什么if条件,即使失败-1 < 8?
在Java中,int类型是有符号的,但它有一个比较两个整数的方法,就好像它们是无符号的一样:
public static int compareUnsigned(int x, int y) {
return compare(x + MIN_VALUE, y + MIN_VALUE);
}
Run Code Online (Sandbox Code Playgroud)
它添加Integer.MIN_VALUE到每个参数,然后调用正常的签名比较方法,即:
public static int compare(int x, int y) {
return (x < y) ? -1 : ((x == y) ? 0 : 1);
}
Run Code Online (Sandbox Code Playgroud)
如何添加MIN_VALUE到每个参数神奇地使比较无符号?
考虑以下代码:
using integer = int; // or any other fundamental integral type
using unsigned_integer = typename std::make_unsigned<integer>::type;
constexpr integer bits = std::numeric_limits<unsigned_integer>::digits;
integer value = -42; // or any value
integer mask = static_cast<integer>(1)<<static_cast<integer>(bits-1);
bool result_and = value & mask;
bool result_or = value | mask;
bool result_xor = value ^ mask;
Run Code Online (Sandbox Code Playgroud)
我想知道根据标准定义的这些操作有多好.我是否有保证在所有架构上获得相同的结果?我肯定会对所有架构上的符号位进行操作,这个符号位0用于正数和1负数?
我想要一个对应于的有符号类型std::size(理想情况下是根据它计算出来的,而不是依赖于另一个可能独立的定义。)自然地,我想到使用std::make_signed_t<std::size_t>.
然而,当我查看时std::ssize,我注意到返回类型是std::common_type_tand std::ptrdiff_t。decltype(c.size())现在c.size()应该是未签名的,但无论哪种情况,它都应该被签名,因为std::ptrdiff_t它是。剩下的就是尺寸了;那应该是两种类型中较大的一个。
我不明白的是为什么你会使用一个大的类型,就像std::ptrdiff_t你想要最大的有符号类型一样。如果它真的是最大的,那就没有意义了std::common_type_t。相反,假设std::common_type_t并不总是返回std::ptrdiff_t,这意味着decltype(c.size())是不同的大小,并且有效地std::ptrdiff_t用于最小大小的有符号类型。如果是这样的话,难道不应该使用最小的有符号类型吗?decltype(c.size())或者说,为什么不直接使用对应的有符号类型呢?该定义背后的意图是什么?
我遇到一种情况,需要将 16 位打包成 64 位数字,然后将它们作为 [ -32768, 32768 ) 范围内的有符号整数读回。我为此选择的方法是将数字计算为有符号 16 位 int,立即将其转换为无符号 16 位 int,然后将其向上转换为 64 位无符号 int,然后执行适当的位移以获得将关键的 16 位放入正确的位置。
这是创建位打包排列的伪代码:
Given int x, y such that x - y >= -32768 and y - x < 32768;
const int MASK_POS = 45;
const unsigned short int u_s = x - y;
unsigned long long int ull_s = u_s;
ull_s <<= MASK_POS;
Run Code Online (Sandbox Code Playgroud)
这是提取原始数字差异的伪代码:
Given unsigned long long int ull_s with 16 bits encoding a signed integer in the 46th …Run Code Online (Sandbox Code Playgroud) 如果我使用的库当前使用特定的数字类型别名,例如
\n\ntypedef uint32_t library_type;\n\nvoid library_function(library_type x);\nRun Code Online (Sandbox Code Playgroud)\n\n即使库更改了其 typedef,我如何确保需要传入不同类型的值的代码保持正确?
\n\nuint64_t x = get_some_number();\n\n// \xe2\x80\xa6need checks here\xe2\x80\xa6\n\nlibrary_function((library_type)x);\nRun Code Online (Sandbox Code Playgroud)\n\n我可以添加以下检查:
\n\nassert(sizeof library_type >= sizeof uint32_t);\nassert(x <= UINT32_MAX);\nRun Code Online (Sandbox Code Playgroud)\n\n第二次检查将确保我得到的值符合当前 的范围library_type。库作者没有提供LIBRARY_TYPE_MAX定义,因此第一个检查试图保护第二个,以防万一library_type将来编译代码时因任何原因发生更改。
第一次检查会捕获 if library_typewere 更改为 eg int8_t,但如果 thelibrary_type更改为 anint32_t该怎么办?它仍然是正确的“尺寸”,但范围仍然小于我正在检查的范围!
C 语言是否提供了一个运算符来内省类型的符号性,就像sizeof让我知道宽度一样?有没有其他方法可以确保library_type只有在正确的情况下才能达到我的演员表?