是什么决定了溢出操作的结果?

时间:2016-01-02 01:49:29

标签: algorithm floating-point bit-manipulation hardware integer-overflow

示例:

void modify_bits(HDC hdc, HBITMAP hbitmap) 
{   //expecting 32-bit bitmap
    BITMAP bm = { 0 };
    GetObject(hbitmap, sizeof(bm), &bm);
    int w = bm.bmWidth;
    int h = bm.bmHeight;
    BITMAPINFOHEADER bmpInfoHeader = { sizeof(BITMAPINFOHEADER),
        w, h, 1, 32, BI_RGB, 0, 0, 0, 0, 0 };
    BYTE* bits = new BYTE[w * h * 4];
    if (GetDIBits(hdc, hbitmap, 0, h, bits, (BITMAPINFO*)&bmpInfoHeader, DIB_RGB_COLORS)) {
        BYTE* p = bits;
        for (int x = 0; x < w; x++) {
            for (int y = 0; y < h; y++) {
                p[3] = 128;
                p[0] = p[0] * p[3] / 255;
                p[1] = p[1] * p[3] / 255;
                p[2] = p[2] * p[3] / 255;
                p += 4;
            }
        }
        SetDIBits(hdc, hbitmap, 0, h, bits, (BITMAPINFO*)&bmpInfoHeader, DIB_RGB_COLORS);
    }
    delete[] bits;
}

void blend2(HDC hdc, RECT rc, HBITMAP hbitmap1, HBITMAP hbitmap2)
{
    int w = rc.right;
    int h = rc.bottom;

    modify_bits(hdc, hbitmap2);

    HDC memdc1 = CreateCompatibleDC(hdc);
    HDC memdc2 = CreateCompatibleDC(hdc);

    BITMAP bmp1, bmp2;
    GetObject(hbitmap1, sizeof(BITMAP), &bmp1);
    GetObject(hbitmap2, sizeof(BITMAP), &bmp2);
    int w1 = bmp1.bmWidth;
    int h1 = bmp1.bmHeight;
    int w2 = bmp2.bmWidth;
    int h2 = bmp2.bmHeight;

    SelectObject(memdc1, hbitmap1);
    SelectObject(memdc2, hbitmap2);

    BLENDFUNCTION blend = { 0 };
    blend.BlendOp = AC_SRC_OVER;
    blend.BlendFlags = 0;
    blend.SourceConstantAlpha = 255;
    blend.AlphaFormat = AC_SRC_ALPHA;

    SetStretchBltMode(hdc, COLORONCOLOR);

    //draw first image normally:
    StretchBlt(hdc, 0, 0, w, h, memdc1, 0, 0, w1, h1, SRCCOPY);

    //AlphaBlend the second image:
    AlphaBlend(hdc, 0, 0, w, h, memdc2, 0, 0, w2, h2, blend);

    DeleteDC(memdc1);
    DeleteDC(memdc2);
}

是什么决定这是否有效?处理器?硬件?语言?帮助我尽可能深入地了解这一点。

3 个答案:

答案 0 :(得分:2)

处理器是硬件(至少就本问题而言)。

这种语言纯粹是一种表达事物的方式,允许它将其转换为处理器本身所期望的内容。这里语言的作用是定义什么&#34; int&#34;意味着什么算术运算符/做什么,以及它们的异常行为是什么。在低级语言(如C / C ++)中,它留下了几个要做的事情&#34;实现定义&#34;,就像整数的溢出行为一样。其他语言(如Python)可以定义&#34; int&#34;成为一个抽象(而不是硬件)概念,从而改变一些规则(如检测溢出和执行自定义行为)。

如果语言留下了某些实现定义,并且实现将该决定卸载到硬件上,那么硬件就是定义代码行为的原因。

答案 1 :(得分:0)

计算机(硬件)代表两个补码中的数字。检查this以获取两个补码的详细信息,以及计算机使用它的原因。

在两个补码中有符号数(暂时不浮动,为简单起见)有一个符号位作为最高有效位。例如:

01111111

在两个补码中代表127。和

10000000

代表-128。在这两个例子中,第一位是符号位,如果它是0,则数字为正,否则为负。

8位有符号数字可以表示-128到127之间的数字,所以如果你添加127和3,你就不会得到130,因为溢出你会得到-126。让我们看看为什么:

 01111111
 00000011
+________
 10000010 which is a negative number, -126 in two's complement.

如果发生溢出,硬件如何理解?另外,例如,如果添加两个正数而结果为负数,则表示溢出。如果你添加两个负数并且结果变为正数则意味着再次溢出。

我希望这将是硬件级别如何发生这些事情的一个很好的例子。

答案 2 :(得分:0)

高级编程语言为人类描述他们想要发生的事情提供了一种方式。编译器将其简化为处理器理解的语言(最终)机器代码。特定处理器的指令集旨在用于执行任务,通用处理器用于通用任务,包括您所描述的任务。与铅笔和纸张数学不同的是,如果我们需要另一列另一个10的幂,99 + 1 = 100例如两个数字宽,3个数字将被放入。处理器有一个固定的寄存器,这并不意味着你不能创造性,但语言和资源(内存,磁盘空间等)有限制。并且处理器要么直接在逻辑中,要么编译器实现正确的指令序列,一般来说,如果你要求它可以并且将检测到溢出。有些处理器比其他处理器更难,有些处理器不够通用,但我不认为我们需要担心这些,你正在阅读这个网页的处理器绝对可以解决这个问题。