我的一位同事询问是否有未签名的双,我说没有,但我仍然检查它,这在Microsoft Visual C++ 2010中编译:
unsigned double a;
double b;
printf("size_a=%d size_b=%d", (int) sizeof(a), (int) sizeof(b));
它输出size_a=4 size_b=8.也就是说,四个字节unsigned double,和八个字节double.
可能重复:
为什么C没有无符号浮点数?
问题可能是非常基本的,可能很早就回答了,但我想了解为什么C++没有无符号浮点类型,即使浮点文字可以是有符号或无符号的.
$ 3.9.1/8-"有三种浮点类型:float,double和long double."
在汇编编程中,想要从寄存器的低位计算某些东西是相当普遍的,这些位不能保证将其他位置零.在像C这样的高级语言中,你只需将输入转换为小尺寸,让编译器决定是否需要分别将每个输入的高位归零,或者是否可以在输出之后切断结果的高位.事实.
这是为x86-64的(又名AMD64),出于各种原因尤其常见1,其中的一些是存在于其它的ISA.
我将使用64位x86作为示例,但目的是询问/讨论2的补码和无符号二进制算法,因为所有现代CPU都使用它.(注意,C和C++不保证两个补码4,并且有符号溢出是未定义的行为.)
作为示例,考虑一个可以编译为LEA指令2的简单函数.(在X86-64 SysV的(Linux)的ABI 3,前两个函数参数是rdi和rsi,与在返回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
gcc知道即使是负有符号整数,加法也只是从右到左,所以输入的高位不会影响进入的内容eax.因此,它保存了一个指令字节并使用 lea  eax,  [rdi + rsi*4 + 3]
为什么它有效?
1为什么x86-64频繁出现这种情况:x86-64有可变长度指令,其中额外的前缀字节改变了操作数大小(从32到64或16),因此在指令中通常可以保存一个字节.以相同的速度执行.当写入低8b或16b的寄存器(或稍后读取完整寄存器(Intel pre-IvB)时的失速)时,它也具有错误依赖性(AMD/P4/Silvermont):由于历史原因, …
我使用Visual Studio,Ubuntu的GCC,英特尔编译器,MinGW测试了右移.所有移位的符号位.我猜Xcode的GCC也是如此.
我知道这种行为是特定于实现的,但看起来所有主要的桌面/服务器编译器都实现了算术移位.是否有任何广泛使用的编译器不会在符号位中移位?
谢谢.
我创建了一个使用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;
双字产品应该是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
使用SSE可以这样做
__m128i xh;    //(xl2, xh2, xl1, xh1) high is signed, low unsigned
__m128i …我正在设计一个简单的玩具指令集和随附的模拟器,并且正在尝试找出支持哪些指令。在算术方面,我目前有无符号加法、减法、乘法和除法。但是,我似乎无法找到以下问题的明确答案:哪些算术运算符需要签名版本,哪些算术运算符的无符号和补码签名版本等效?
例如,1111 的补码等于 -1。如果你加 1 并假装它是一个无符号数,你会得到 0000,即使将其视为 -1,这也是正确的。然而,这对所有数字都适用吗?那么其他三个运算(减法、乘法、除法)呢?
在Java中,int类型是有符号的,但它有一个比较两个整数的方法,就好像它们是无符号的一样:
public static int compareUnsigned(int x, int y) {
    return compare(x + MIN_VALUE, y + MIN_VALUE);
}
它添加Integer.MIN_VALUE到每个参数,然后调用正常的签名比较方法,即:
public static int compare(int x, int y) {
    return (x < y) ? -1 : ((x == y) ? 0 : 1);
}
如何添加MIN_VALUE到每个参数神奇地使比较无符号?
我想比较两个 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
但8080并不是Z80的严格子集,上面的代码在那里不起作用——在8080上,算术指令根据结果的奇偶校验设置P标志,结果很搞笑。
那么在 8080 上进行带符号比较的惯用方法是什么?
实际上计算溢出标志是可能的,但确实很痛苦,因为它需要对操作数和结果进行位操作,而且我的寄存器已经用完了。而且,这实际上并不是我想要的;我实际上并不关心溢出。我只是想做个比较。
(如果结果为负,我不能简单地进行减法和分支,因为这并不适用于所有情况。考虑 INT_MIN < INT_MAX。即 0x8000 - 0x7fff = 1,这显然是正数。)
我需要在 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;
有谁知道出了什么问题?
编辑 我不知道“无符号双精度”等于“无符号浮点数”,然后我不知道我必须将问题的答案作为“C 中的无符号浮点数?” 无论如何,在阅读这篇文章后,我接受了我的问题“重复”。我建议删除这个问题。
我有一系列的整数
var ints = [R,B,G,A]
我想使用shift来获得32位表示
var thirtyTwo = AGBR
例如,
[255.0, 0.0, 0.0, 255.0] => 0xFF0000FF => 4278190335
我试图通过循环和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;
}
但主要的问题是,当我将255.0移位到<< 24时,我得到一个负数
255.0 << 24 = -16777216    
这告诉我,我要么有点限制,要么签署了res.我认为Javascript中的所有按位操作都是在无符号的32位浮点数上,所以不确定这里发生了什么.救命?
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
}
替换第5行
float f = 1.0;
使程序工作.为什么会这样?
我正在开发visual studio 2005.
c++ ×4
c ×3
integer ×3
assembly ×2
binary ×2
comparison ×2
signed ×2
x86 ×2
instructions ×1
intel-8080 ×1
javascript ×1
sse ×1
struct ×1
unsigned ×1
visual-c++ ×1