相关疑难解决方法(0)

为什么sizeof(无符号双精度)等于4?

我的一位同事询问是否有未签名的双,我说没有,但我仍然检查它,这在Microsoft Visual C++ 2010中编译:

unsigned double a;
double b;
printf("size_a=%d size_b=%d", (int) sizeof(a), (int) sizeof(b));
Run Code Online (Sandbox Code Playgroud)

它输出size_a=4 size_b=8.也就是说,四个字节unsigned double,和八个字节double.

c++ visual-studio-2010

71
推荐指数
3
解决办法
3698
查看次数

为什么没有无符号浮点类型?

可能重复:
为什么C没有无符号浮点数?

问题可能是非常基本的,可能很早就回答了,但我想了解为什么C++没有无符号浮点类型,即使浮点文字可以是有符号或无符号的.

$ 3.9.1/8-"有三种浮点类型:float,double和long double."

c++ floating-point

15
推荐指数
2
解决办法
2万
查看次数

如果只需要结果的低部分,那么可以使用哪个2的补码整数运算而不将输入中的高位置零?

在汇编编程中,想要从寄存器的低位计算某些东西是相当普遍的,这些位不能保证将其他位置零.在像C这样的高级语言中,你只需将输入转换为小尺寸,让编译器决定是否需要分别将每个输入的高位归零,或者是否可以在输出之后切断结果的高位.事实.

这是为x86-64的(又名AMD64),出于各种原因尤其常见1,其中的一些是存在于其它的ISA.

我将使用64位x86作为示例,但目的是询问/讨论2的补码和无符号二进制算法,因为所有现代CPU都使用它.(注意,C和C++不保证两个补码4,并且有符号溢出是未定义的行为.)

作为示例,考虑一个可以编译为LEA指令2的简单函数.(在X86-64 SysV的(Linux)的ABI 3,前两个函数参数是rdirsi,与在返回rax. int是一个32位的类型.)

; int intfunc(int a, int b) { return a + b*4 + 3; }
intfunc:
    lea  eax,  [edi + esi*4 + 3]  ; the obvious choice, but gcc can do better
    ret
Run Code Online (Sandbox Code Playgroud)

gcc知道即使是负有符号整数,加法也只是从右到左,所以输入的高位不会影响进入的内容eax.因此,它保存了一个指令字节并使用 lea eax, [rdi + rsi*4 + 3]

哪些其他操作具有结果低位的这种属性而不依赖于输入的高位?

为什么它有效?



脚注

1为什么x86-64频繁出现这种情况:x86-64有可变长度指令,其中额外的前缀字节改变了操作数大小(从32到64或16),因此在指令中通常可以保存一个字节.以相同的速度执行.当写入低8b或16b的寄存器(或稍后读取完整寄存器(Intel pre-IvB)时的失速)时,它也具有错误依赖性(AMD/P4/Silvermont):由于历史原因, …

binary x86 assembly integer twos-complement

12
推荐指数
1
解决办法
928
查看次数

签名右移:哪个编译器使用逻辑移位

我使用Visual Studio,Ubuntu的GCC,英特尔编译器,MinGW测试了右移.所有移位的符号位.我猜Xcode的GCC也是如此.

我知道这种行为是特定于实现的,但看起来所有主要的桌面/服务器编译器都实现了算术移位.是否有任何广泛使用的编译器不会在符号位中移位?

谢谢.

c c++

11
推荐指数
1
解决办法
6010
查看次数

SIMD使用无符号乘法对64位*64位到128位进行签名

我创建了一个使用SIMD进行64位*64位到128位的功能.目前我已经使用SSE2(acutally SSE4.1)实现了它.这意味着它可以同时运行两个64b*64b到128b的产品.同样的想法可以扩展到AVX2或AVX512,同时提供四个或八个64b*64到128b的产品.我的算法基于http://www.hackersdelight.org/hdcodetxt/muldws.c.txt

该算法进行一次无符号乘法,一次有符号乘法和两次有符号*无符号乘法.签名的*signed和unsigned*unsigned操作很容易使用_mm_mul_epi32_mm_mul_epu32.但混合签名和未签名的产品给我带来了麻烦.例如,考虑一下.

int32_t x = 0x80000000;
uint32_t y = 0x7fffffff;
int64_t z = (int64_t)x*y;
Run Code Online (Sandbox Code Playgroud)

双字产品应该是0xc000000080000000.但是如果你假设你的编译器知道如何处理混合类型,你怎么能得到这个呢?这就是我想出的:

int64_t sign = x<0; sign*=-1;        //get the sign and make it all ones
uint32_t t = abs(x);                 //if x<0 take two's complement again
uint64_t prod = (uint64_t)t*y;       //unsigned product
int64_t z = (prod ^ sign) - sign;    //take two's complement based on the sign
Run Code Online (Sandbox Code Playgroud)

使用SSE可以这样做

__m128i xh;    //(xl2, xh2, xl1, xh1) high is signed, low unsigned
__m128i …
Run Code Online (Sandbox Code Playgroud)

c x86 integer sse bit-manipulation

9
推荐指数
2
解决办法
4203
查看次数

对于无符号数和有符号数的补码,哪些算术运算是相同的?

我正在设计一个简单的玩具指令集和随附的模拟器,并且正在尝试找出支持哪些指令。在算术方面,我目前有无符号加法、减法、乘法和除法。但是,我似乎无法找到以下问题的明确答案:哪些算术运算符需要签名版本,哪些算术运算符的无符号和补码签名版本等效?

例如,1111 的补码等于 -1。如果你加 1 并假装它是一个无符号数,你会得到 0000,即使将其视为 -1,这也是正确的。然而,这对所有数字都适用吗?那么其他三个运算(减法、乘法、除法)呢?

binary instruction-set instructions twos-complement

7
推荐指数
2
解决办法
2458
查看次数

添加MIN_VALUE如何将整数比较为无符号?

在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到每个参数神奇地使比较无符号?

language-agnostic comparison unsigned signed integer

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

如何在 8080 上高效地进行签名比较?

我想比较两个 16 位数字并根据结果进行分支:相当于if (a<b) goto negative. 我使用的是英特尔 8080。

Z80 有一个有符号算术溢出标志,可以通过一定程度的努力来实现此目的。标准代码是:

ld de, _left
ld hl, _right
ld a, e
sub a, l
ld a, d
sbc a, h
jp po, $+5  ; branch on overflow flag not set
xor a, 0x80 ; flip sign bit
jm negative ; actually do the test
Run Code Online (Sandbox Code Playgroud)

但8080并不是Z80的严格子集,上面的代码在那里不起作用——在8080上,算术指令根据结果的奇偶校验设置P标志,结果很搞笑。

那么在 8080 上进行带符号比较的惯用方法是什么?

实际上计算溢出标志是可能的,但确实很痛苦,因为它需要对操作数和结果进行位操作,而且我的寄存器已经用完了。而且,这实际上并不是我想要的;我实际上并不关心溢出。我只是想做个比较。

(如果结果为负,我不能简单地进行减法和分支,因为这并不适用于所有情况。考虑 INT_MIN < INT_MAX。即 0x8000 - 0x7fff = 1,这显然是正数。)

comparison assembly signed intel-8080

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

C中的无符号双精度?

我需要在 C 结构中使用 unsigned double,但我无法编译。错误提示:“myvar”的短、有符号或无符号无效

这是我的代码:

#include <stdlib.h>
#include <stdio.h>

struct eReg{
   int key;
   unsigned char a;
   unsigned short int b;
   unsigned double myvar;
   }MyReg;
Run Code Online (Sandbox Code Playgroud)

有谁知道出了什么问题?

编辑 我不知道“无符号双精度”等于“无符号浮点数”,然后我不知道我必须将问题的答案作为“C 中的无符号浮点数?” 无论如何,在阅读这篇文章后,我接受了我的问题“重复”。我建议删除这个问题。

c struct

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

Javascript位移到32位

我有一系列的整数

var ints = [R,B,G,A]
Run Code Online (Sandbox Code Playgroud)

我想使用shift来获得32位表示

var thirtyTwo = AGBR
Run Code Online (Sandbox Code Playgroud)

例如,

[255.0, 0.0, 0.0, 255.0] => 0xFF0000FF => 4278190335
Run Code Online (Sandbox Code Playgroud)

我试图通过循环和bitshift来做到这一点:

function cArrayToABGR(va) {
    var res = 0;
    for (var i = 0; i < va.length; ++i) {
        var color = va[i];
        color <<= (8 * i);
        res += color;
    }
    return res;
}
Run Code Online (Sandbox Code Playgroud)

但主要的问题是,当我将255.0移位到<< 24时,我得到一个负数

255.0 << 24 = -16777216    
Run Code Online (Sandbox Code Playgroud)

这告诉我,我要么有点限制,要么签署了res.我认为Javascript中的所有按位操作都是在无符号的32位浮点数上,所以不确定这里发生了什么.救命?

javascript bit-manipulation

2
推荐指数
2
解决办法
625
查看次数

如果使用unsigned,为什么重载会导致模糊调用?

void foo(int,int) {}
void foo(int ,float) {}
void foo(float,int) {}

void main()
{
  unsigned int i = 10;
  unsigned float f = 1.0;       //line 5
  foo(i,f); // ambiguous call error
}
Run Code Online (Sandbox Code Playgroud)

替换第5行

float f = 1.0;
Run Code Online (Sandbox Code Playgroud)

使程序工作.为什么会这样?

我正在开发visual studio 2005.

c++ visual-c++

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