2013-08-25 7 views
1

У меня встроенный 16-битный процессор. На этой машине ints имеет ширину 16 бит и поддерживает длинные ширины 32 бит. Мне нужно сделать некоторые умножения, которые нужно будет хранить в 64 битах (например, умножить 32-разрядное число на 16-битное число). Как я могу это сделать с заданными ограничениями? У меня нет математической библиотеки для этого.Как сделать 64-битное умножение на 16-битной машине?

+1

Вам нужна математическая библиотека, которая предоставляет такой сервис как вызов функции. – RenniePet

+1

Ну ... вы не предоставляете достаточно информации. Вы программируете это на ассемблере или C или что-то еще? Вам нужно будет получить или написать себе функцию или подпрограмму, которая выполняет умножение. Попробуйте выполнить поиск в Google «имя микропроцессорной математической библиотеки». Если возможно, с открытым исходным кодом, то вы можете увидеть исходный код, как это делается, и просто скопировать инструкции, если вы не хотите включать всю библиотеку в свою программу. (Это не моя область знаний, 35 лет с тех пор, как я занимался подобным программированием, я поражен тем, что это по-прежнему необходимо.) – RenniePet

+0

Это может помочь, если вы укажете имя микропроцессора, вместо того, чтобы просто сказать «встроенный 16-разрядный процессор ». – RenniePet

ответ

3

Предложение в C. Обратите внимание, что этот код, вероятно, будет проще реализовать с помощью встроенного ассемблера, как обнаружение переноса в C не кажется, что легко

// Change the typedefs to what your compiler expects 
typedef unsigned __int16  uint16 ; 
typedef unsigned __int32  uint32 ; 

// The 64bit int 
typedef struct uint64__ 
{ 
    uint32  lower ; 
    uint32  upper ; 
} uint64; 

typedef int boolt; 

typedef struct addresult32__ 
{ 
    uint32  result ; 
    boolt  carry ; 
} addresult32; 

// Adds with carry. There doesn't seem to be 
// a real good way to do this is in C so I 
// cheated here. Typically in assembler one 
// would detect the carry after the add operation 
addresult32 add32(uint32 left, uint32 right) 
{ 
    unsigned __int64 res; 
    addresult32 result ; 

    res = left; 
    res += right; 


    result.result = res & 0xFFFFFFFF; 
    result.carry = (res - result.result) != 0; 

    return result; 
} 

// Multiplies two 32bit ints 
uint64 multiply32(uint32 left, uint32 right) 
{ 
    uint32 lleft, uleft, lright, uright, a, b, c, d; 
    addresult32 sr1, sr2; 
    uint64 result; 

    // Make 16 bit integers but keep them in 32 bit integer 
    // to retain the higher bits 

    lleft = left   & 0xFFFF; 
    lright = right   & 0xFFFF; 
    uleft = (left >> 16) ; 
    uright = (right >> 16) ; 

    a = lleft * lright; 
    b = lleft * uright; 
    c = uleft * lright; 
    d = uleft * uright; 

    sr1 = add32(a, (b << 16)); 
    sr2 = add32(sr1.result, (c << 16)); 

    result.lower = sr2.result; 
    result.upper = d + (b >> 16) + (c >> 16); 
    if (sr1.carry) 
    { 
     ++result.upper; 
    } 

    if (sr2.carry) 
    { 
     ++result.upper; 
    } 

    return result; 
}