PDA

View Full Version : Bài tập C Thuật toán cộng trừ số hexa trong lập trình C?



thienbk89
27-05-2010, 11:51 PM
mình đang bí cách cộng trừ nhân chia số hexa ai biết chỉ mình với

chjp xinh kut3
28-05-2010, 12:51 PM
tính theo số thập phân bình thường, rồi đổi kq sang hexa.

conrongchautien
28-05-2010, 03:33 PM
Bài này làm hơi "chuối". Ai có cách gọn hơn thì post lên tham khảo nhé:

/* Cac phep tinh tren so he Hexadecimal */
#include<stdio.h>
#include<conio.h>
#include<math.h>
#include<string.h>

int i;
void chuyendoi(int so,int he)
{
if(so<0)
{
so=-so;
printf("-");
if (so>=he) chuyendoi(so/he,he);
printf("%c",(so%he)["0123456789ABCDEF"]);
}
else
{
if (so>=he) chuyendoi(so/he,he);
printf("%c",(so%he)["0123456789ABCDEF"]);
}
}

int DCS(char s[], int n)
{

int a;
switch(s[n-1])
{
case '0' : a=0; break;
case '1' : a=1; break;
case '2' : a=2; break;
case '3' : a=3; break;
case '4' : a=4; break;
case '5' : a=5; break;
case '6' : a=6; break;
case '7' : a=7; break;
case '8' : a=8; break;
case '9' : a=9; break;
case 'A' : case 'a' : a=10; break;
case 'B' : case 'b' : a=11; break;
case 'C' : case 'c' : a=12; break;
case 'D' : case 'd' : a=13; break;
case 'E' : case 'e' : a=14; break;
case 'F' : case 'f' : a=15; break;
}
return n?a*(int)pow(16,i++)+DCS(s,n-1):0;
}

void main()
{
char s1[20]="384",s2[20]="3e8";
int a, b;
i=0;
a=DCS(s1,strlen(s1));
i=0;
b=DCS(s2,strlen(s2));
printf("Tong %s + %s : ",s1,s2);
chuyendoi((a+b) , 16);
printf("\nHieu %s + %s : ",s1,s2);
chuyendoi((a-b) , 16);
printf("\nTich %s + %s : ",s1,s2);
chuyendoi((a*b) , 16);
printf("\nThuong %s + %s : ",s1,s2);;
chuyendoi((a/b) , 16);
getch();
}

langman
28-05-2010, 05:42 PM
tớ hơi gà nhưng mà tớ nhớ ngày xưa học tư tưởng cộng
rồi với tư tưởng cộng 2 số đó tớ áp dụng được cả số trong các loại hệ cơ số khác nhau mà

hoặc thế này


#include <stdio.h>
#include <conio.h>
void main()
{
int a,b;
scanf("%x %x",&a,&b);
printf("%x ",a+b);
getch();
}

panfider
28-05-2010, 06:27 PM
tại hạ mạn hỏi, hexa là gì vậy?

trihn_kt
28-05-2010, 06:31 PM
tại hạ mạn hỏi, hexa là gì vậy?

Hệ đếm thập lục phân (16)

tauit_dnmd
28-05-2010, 06:48 PM
Hệ đếm thập lục phân (16)

hệ đếm thâp lục phân là thế nào thế anh ơi.em gà có j sai anh chi giáo em với :D:D:D:D:D

donvuon
28-05-2010, 07:02 PM
mình đang bí cách cộng trừ nhân chia số hexa ai biết chỉ mình với

Tham khảo đây xem sao.

#include <stdio.h>
#define minussign '-'
#define max 1000
#define base 16

char str16[] = "0123456789ABCDEF";

class hexa
{
char s[max];
public:
hexa();
hexa(const hexa &);
hexa(char *);
hexa(int);
void show(char *ch = " ");
int len();
void reverse();
char &operator [](int k) {return s[k];}
hexa add(hexa);
hexa sub(hexa);

hexa operator - ();
int operator < (hexa);
int operator > (hexa);
int operator <= (hexa);
int operator >= (hexa);
int operator == (hexa);

int operator < (int);
int operator > (int);
int operator <= (int);
int operator >= (int);
int operator == (int);

friend int operator < (int, hexa);
friend int operator > (int, hexa);
friend int operator <= (int, hexa);
friend int operator >= (int, hexa);
friend int operator == (int, hexa);

hexa operator + (hexa);
hexa operator + (int);
hexa operator ++ ();
hexa operator ++ (int);
friend hexa operator + (int, hexa);

hexa operator - (hexa);
hexa operator - (int);
hexa operator -- ();
friend hexa operator - (int, hexa);

hexa operator += (hexa);
hexa operator -= (hexa);

hexa operator * (int);
friend hexa operator * (int, hexa);
hexa operator * (hexa);
hexa operator *= (hexa);
hexa operator /= (hexa);
hexa operator / (hexa);
hexa operator / (int);
friend hexa operator % (hexa,hexa);

friend hexa sqrt(hexa);
friend hexa sqrt(long);
hexa pow(hexa, unsigned int);
friend hexa pow(hexa, hexa);
friend int isprime(hexa);
};

int strrevcmp(char *a, char *b)
{
int aj = 0, bj=0;
while (a[aj]) aj++;
while (aj && a[--aj]=='0');

while (b[bj]) bj++;
while (bj && b[--bj]=='0');

while (aj && bj && a[aj]==b[bj]) {aj--; bj--;}
if (aj > bj) return 1;
if (aj < bj) return -1;
return a[aj] - b[bj];
}

int val(char ch)
{
int p = 0;
while (str16[p] != ch) p++;
return p;
}
char chr(int num)
{
return str16[num];
}

char addchr(char a, char b, int &carry)
{
int temp = val(a) + val(b) + carry;
carry = temp/base;
return chr(temp %base);
}

char subchr(char a, char b, int &carry)
{
int temp = base + val(a) - val(b) - carry;
carry = 1 - temp/base;
return chr(temp %base);
}

void hexa::show(char *ch)
{
hexa b = *this;
b.reverse();
printf("0x%s%s",b.s,ch);
}

int hexa::len()
{
int k = 0;
while (s[k]) k++;
return k;
}

hexa::hexa() {s[0] = '0'; s[1] = 0;}

hexa::hexa(char *str)
{
int k=0;
while (*str == '0') str++;
if (*str==0) {s[0] = '0'; s[1] = 0;}
else
{
while (*str) s[k++] = *str++;
s[k] = 0;
reverse();
}
}

hexa ::hexa(int value)
{
if(value ==0) {s[0] = '0'; s[1]=0;}
else
{
int remainder, k = 0;
int sign = 0;
if (value < 0) {value =-value; sign = 1;}
while (value)
{
remainder = value % base;
value /= base;
s[k++] = chr(remainder);
}
if (sign) s[k++] = minussign;
s[k] = 0;
}
}

hexa ::hexa(const hexa &b) { *this = b;}

void hexa::reverse()
{
int slen = len();
char temp;
for (int j=0; j < slen/2; j++)
{
temp = s[slen -j-1];
s[slen-j-1]= s[j];
s[j] = temp;
}
}

hexa hexa::add (hexa b)
{
hexa result;
int sj = 0, bj = 0, i = 0, carry = 0;
while(s[sj] && b[bj]) result[i++] = addchr(s[sj++],b[bj++],carry);
while (s[sj]) result[i++] = addchr(s[sj++],'0',carry);
while (b[bj]) result[i++] = addchr(b[bj++],'0',carry);
if (carry) result[i++] = chr(carry);
result[i] = 0;
return result;
}


hexa hexa::sub (hexa b)
{
hexa result;
int sj = 0, bj = 0, i = 0, carry = 0;

while (s[sj] && b[bj]) result[i++] = subchr(s[sj++],b[bj++],carry);
while (s[sj]) result[i++] = subchr(s[sj++],'0',carry);
while (i > 0 && result[--i] == '0');

result[++i] =0;
return result;
}

hexa hexa::operator - ()
{
hexa a = *this;
int slen = a.len();
if (a.s[slen-1] == minussign) a.s[slen-1] = 0;
else {a.s[slen] = minussign; a.s[slen+1]=0;}
return a;
}

int hexa::operator < (hexa b)
{
hexa temp = *this;
int sign = (temp[temp.len()-1] == minussign);
int bsign = (b[b.len()-1] == minussign);
if (sign && bsign) return strrevcmp((-temp).s,(-b).s) > 0;
if (!sign && !bsign) return strrevcmp(temp.s,b.s) < 0;
if (sign && !bsign) return 1;
return 0;
}


int hexa::operator > (hexa b) {return b < *this; }

int hexa::operator <= (hexa b) {return !(b < *this);}

int hexa::operator >= (hexa b) {return !(*this < b);}

int hexa::operator == (hexa b) {return !(*this < b) && !(b < *this);}

int hexa::operator < (int x) {return *this < hexa(x);}
int hexa::operator > (int x) {return *this > hexa(x);}
int hexa::operator <= (int x) {return *this <= hexa(x);}
int hexa::operator >= (int x) {return *this >= hexa(x);}
int hexa::operator == (int x) {return *this == hexa(x);}

int operator < (int x, hexa a) {return a > x;}
int operator > (int x, hexa a) {return a < x;}
int operator <= (int x, hexa a) {return a >= x;}
int operator >= (int x, hexa a) {return a <= x;}
int operator == (int x, hexa a) {return a == x;}

hexa operator + (int x, hexa a) {return a + x;}
hexa operator - (int x, hexa a) {return a - x;}

hexa hexa::operator + (int value) {return *this + hexa(value);}

hexa hexa::operator - (int value) {return *this - hexa(value);}

hexa hexa::operator ++ () {*this += 1; return *this;}
hexa hexa::operator ++ (int) {return ++*this;}
hexa hexa::operator -- () {*this -= 1; return *this;}

hexa hexa::operator + (hexa b)
{
hexa a = *this;
int asign = a < 0, bsign = b < 0;
int alen = a.len(), blen = b.len();
if (asign) a[alen-1] = 0;
if (bsign) b[blen-1]=0;

if (!asign && !bsign) return a.add(b);
if (asign && bsign) return -(a.add(b));
if (!asign && bsign)
{
if (strrevcmp(a.s,b.s) >= 0) return a.sub(b);
else return -(b.sub(a));
}
return (b + -a);
}

hexa hexa::operator - (hexa b) {return (*this) + (-b);}

hexa hexa::operator += (hexa b)
{
*this = *this + b;
return *this;
}

hexa hexa::operator -= (hexa b)
{
*this = *this - b;
return *this;
}

hexa hexa::operator * (int factor)
{
hexa a;
for (int k = 0; k < factor; k++) a += (*this);
return a;
}

hexa hexa::operator *= (hexa b)
{
*this = *this * b;
return *this;
}

hexa hexa::operator /= (hexa b)
{
*this = *this / b;
return *this;
}

hexa operator * (int factor, hexa a) {return a*factor;}

hexa hexa::operator * (hexa b)
{
hexa result; int blen = b.len();
int bsign = b < 0;
if (bsign) b[--blen] = 0;
b.reverse();
for (int k = 0; k < blen; k++)
result = result*base + val(b[k])*(*this);
return bsign ? -result : result;
}

hexa hexa::operator / (hexa b)
{
hexa result, temp = *this;
int bsign = b < 0, blen = b.len();
if (bsign) b[--blen] = 0;
while (temp >= b)
{
temp -= b;
result += 1;
}
return bsign ? -result : result;
}

hexa hexa::operator / (int factor) {return *this /hexa(factor);}

hexa sqrt(hexa number)
{
hexa m(1),sum(1);
while (sum <= number)
{
m += 2;
sum += m;
}
return m/2;
}

hexa sqrt(long number)
{
return sqrt(hexa(number));
}

hexa pow(hexa x, hexa y)
{
hexa result(1);
while (y > 0)
{
result *= x;
y -= 1;
}
return result;
}

hexa pow(hexa a, int x) {return pow(a,hexa(x));}

hexa operator % (hexa a, hexa b)
{
while (a >= b) a -= b;
return a;
}

int isprime(hexa num)
{
hexa k = 2, m = sqrt(num);
while ((k <= m) && (num % k > 0)) k +=1;
return k > m;
}

void main()
{
hexa m(100),n(300);
m.show("<");printf("= cac so nguyen to <= ");n.show("\n\n");
for (hexa k = m; k <= n; k++)
if (isprime(k)) k.show("\t");
printf("\n");

hexa a("123456789"), b("2345678");
printf("\n"); a.show(" + "); b.show(" = ");(a+b).show("\n");
printf("\n"); a.show(" - "); b.show(" = ");(a-b).show("\n");
printf("\n"); a.show(" * "); b.show(" = ");(a*b).show("\n");
printf("\n"); a.show(" / "); b.show(" = ");(a/b).show("\n");
printf("\n"); a.show(" % "); b.show(" = ");(a%b).show("\n");
}

conrongchautien
28-05-2010, 08:09 PM
hoặc thế này


#include <stdio.h>
#include <conio.h>
void main()
{
int a,b;
scanf("%x %x",&a,&b);
printf("%x ",a+b);
getch();
}
Hệ 16 có phép chia chính xác như kiểu chia số thực không huynh langman ... sẵn nhờ huynh chuyển số thực sang số hệ 16. Thanks

trungkien45
28-05-2010, 09:23 PM
Hệ 16 có phép chia chính xác như kiểu chia số thực không huynh langman ... sẵn nhờ huynh chuyển số thực sang số hệ 16. Thanks

phép chia số thực là chính xác ????????????

Số thực được lưu trử trong máy tính là số gần đúng.
Chuyển số thực cần phải xây dựng lại các thuật toán (:-)$

@tauit_dnmd: http://vi.wikipedia.org/wiki/H%E1%BB%87_%C4%91%E1%BA%BFm_th%E1%BA%ADp_l%E1%BB%A 5c_ph%C3%A2n

tauit_dnmd
28-05-2010, 09:36 PM
phép chia số thực là chính xác ????????????

Số thực được lưu trử trong máy tính là số gần đúng.
Chuyển số thực cần phải xây dựng lại các thuật toán (:-)$

@tauit_dnmd: http://vi.wikipedia.org/wiki/H%E1%BB%87_%C4%91%E1%BA%BFm_th%E1%BA%ADp_l%E1%BB%A 5c_ph%C3%A2n

em đọc mà chẳng hiểu hEXa là cái j anh à.em mới học C nên em gà không biết j về C cả mong anh chỉ rõ cho em cái thằng hexa là cái số j đi anh (:X)(:X)(:X):D:D:D:D

trungkien45
28-05-2010, 09:49 PM
Là một hệ đếm dùng 16 kí tự (gì cũng đươc :D)
Thường thì lấy từ 0 đến 9 và A đến F. nếu cái này khó hiểu thì bạn tìm trên google đi

tauit_dnmd
28-05-2010, 09:54 PM
Là một hệ đếm dùng 16 kí tự (gì cũng đươc :D)
Thường thì lấy từ 0 đến 9 và A đến F. nếu cái này khó hiểu thì bạn tìm trên google đi

sao họ không dùng từ A->Z mà lại dùng kiểu đoa anh nhỉ

chjp xinh kut3
28-05-2010, 09:55 PM
em đọc mà chẳng hiểu hEXa là cái j anh à.em mới học C nên em gà không biết j về C cả mong anh chỉ rõ cho em cái thằng hexa là cái số j đi anh (:X)(:X)(:X):D:D:D:D
huhu, đến khóc mất. như hệ cơ số 2 là nhị phân thì hexa là hệ cơ số 16. Vậy thôi


1- Khác với hệ đếm thập phân (gồm 10 ký tự 0, 1, 2, 3, 4, 5, 6, 7, 8, 9; số đứng bên trái lớn hơn số đứng liền kề bên phải nó đúng 10 lần) hệ đếm nhị phân chỉ gồm 2 ký tự 0 và 1 ứng với 2 trạng thái dòng điện là tắt (0) và bật (1) và số đứng bên trai lớn hơn số đứng liền kề với nó bên phải đúng 2 lần. Ví dụ:

Ở hệ đếm thập phân ký hiệu 99 có gía trị thực là: 9x10 mũ1 +9x10 mũ 0 = 9x10 + 9x1 = 99

Ở hệ đếm nhị phân ký hiệu 11 có giá trị thực là: 1x 2 mũ 1 + 1x 2mũ 0 = 1x2 + 1x1 = 3

Trong hệ đếm thập lục (16, còn gọi là Hexa Decimal) ta đã có sẵn 10 ký hiệu đầu từ 0 tới 9, còn thiếu 6 ký tự nữa nên người ta bổ xung thêm A, B, C, D, E, F vào ứng với các giá trị 10, 11, 12, 13, 14, 15

2 - Từ các quy tắc và tương tự như tui đã diễn giải để tìm giá trị thực ở trên, nhằm Cụ thể hơn để tiện so sánh cách viết ký hiệu và giá trị thực của số người ta đã lập ra bảng sau :

Hệ đếm nhị phân Hệ đếm thập phân Hệ đếm thập lục
0000 0 0
0001 1 1
0010 2 2
0011 3 3
0100 4 4
0101 5 5
0110 6 6
0111 7 7
1000 8 8
1001 9 9
1010 10 A
1011 11 B
1100 12 C
1101 13 D
1110 14 E
1111 15 F

conrongchautien
28-05-2010, 10:20 PM
Có đoạn nói về số vô tỉ trong hệ 16. Nhưng sử dụng chắc :((
Phân số

Tương tự như các hệ đếm khác, hệ thập lục phân cũng có thể dùng để biểu thị phân số (vulgar fraction), song chu kỳ thập phân tái diễn (recurring digits) thường xảy ra, do số 16 chỉ có một thừa số nguyên tố:

1/ 0x1 = 0x1
1/ 0x5 = 0x0.3
1/ 0x9 = 0x0.1C7
1/ 0xD = 0x0.13B
1/ 0x2 = 0x0.8
1/ 0x6 = 0x0.2A
1/ 0xA = 0x0.19
1/ 0xE = 0x0.1249
1/ 0x3 = 0x0.5
1/ 0x7 = 0x0.249
1/ 0xB = 0x0.1745D
1/ 0xF = 0x0.1
1/ 0x4 = 0x0.4
1/ 0x8 = 0x0.2
1/ 0xC= 0x0.15
1/ 0x10 = 0x0.1

Do cơ số 16 là bình phương của 4 (4²), phân số thập lục phân có chu kỳ lặp lại cá biệt, xảy ra nhiều lần hơn, so với những số thập phân. Chu kỳ thập phân xảy ra khi mẫu số, với thừa số thấp nhất (denominator in lowest terms), có một thừa số nguyên tố không thấy ở trong hàng cơ số. Trong trường hợp số thập lục phân, tất cả những phân số có mẫu số không phải là tích của một số mũ 2, sẽ tạo nên một chu kỳ thập phân tái diễn.

toanoi02020
10-11-2010, 02:41 PM
Bài này làm hơi "chuối". Ai có cách gọn hơn thì post lên tham khảo nhé:

/* Cac phep tinh tren so he Hexadecimal */
#include<stdio.h>
#include<conio.h>
#include<math.h>
#include<string.h>

int i;
void chuyendoi(int so,int he)
{
if(so<0)
{
so=-so;
printf("-");
if (so>=he) chuyendoi(so/he,he);
printf("%c",(so%he)["0123456789ABCDEF"]);
}
else
{
if (so>=he) chuyendoi(so/he,he);
printf("%c",(so%he)["0123456789ABCDEF"]);
}
}

int DCS(char s[], int n)
{

int a;
switch(s[n-1])
{
case '0' : a=0; break;
case '1' : a=1; break;
case '2' : a=2; break;
case '3' : a=3; break;
case '4' : a=4; break;
case '5' : a=5; break;
case '6' : a=6; break;
case '7' : a=7; break;
case '8' : a=8; break;
case '9' : a=9; break;
case 'A' : case 'a' : a=10; break;
case 'B' : case 'b' : a=11; break;
case 'C' : case 'c' : a=12; break;
case 'D' : case 'd' : a=13; break;
case 'E' : case 'e' : a=14; break;
case 'F' : case 'f' : a=15; break;
}
return n?a*(int)pow(16,i++)+DCS(s,n-1):0;
}

void main()
{
char s1[20]="384",s2[20]="3e8";
int a, b;
i=0;
a=DCS(s1,strlen(s1));
i=0;
b=DCS(s2,strlen(s2));
printf("Tong %s + %s : ",s1,s2);
chuyendoi((a+b) , 16);
printf("\nHieu %s + %s : ",s1,s2);
chuyendoi((a-b) , 16);
printf("\nTich %s + %s : ",s1,s2);
chuyendoi((a*b) , 16);
printf("\nThuong %s + %s : ",s1,s2);;
chuyendoi((a/b) , 16);
getch();
}


các bạn giải thích cho mình đoạn chương trình trên được ko
mình đang làm bài Cộng hai số hexa với độ dài 50 chữ số sử dụng thuộc tính và phương thức liên quan( class ) khó quá mà ko làm được cũng chẳng thấy bài nào mà tham khảo ai giúp thì " thank you very much " bạn nào có bài tham khảo thì sent links or gửi lên nhé ^^ Thân!


Note:

void chuyendoi(int so,int he)
{
if(so<0)
{
so=-so;
printf("-");
if (so>=he) chuyendoi(so/he,he);
printf("%c",(so%he)["0123456789ABCDEF"]);
}
else
{
if (so>=he) chuyendoi(so/he,he);
printf("%c",(so%he)["0123456789ABCDEF"]);
}
}
// return n?a*(int)pow(16,i++)+DCS(s,n-1):0;

rox_rook
11-11-2010, 10:34 PM
Hello,


(so%he)["0123456789ABCDEF"]

Trong bài này nó có một cái "trick" nhỏ mà mình nghĩ là newbie thì ít ai biết tới nó.
- % là lấy phần dư vì vậy nếu gọi m = so % he thì 0 <= m < he
- "0123456789ABCDEF" trong C/C++ là const char*
- phép toán của mãng nó có tính chất hoán vị:


array[ i ] = *( array + i ) = *( i + array ) = i[ array ];

Cái này là cái trick thôi, vì vậy thằng kia tương đương:


const char* str = ""0123456789ABCDEF";
<-> str[ so % he ];

toanoi02020
11-11-2010, 11:17 PM
uhm thanks nghe có vẻ hiếu hiểu nhưng mà bây h dùng ( class )để xây dựng các thuộc tính và phương thức để cộng 2 số hexa với độ dài trong khoảng 1000 thì làm như thế nào xin mời U chỉ giúp
( gợi ý cũng được tại hạ còn kém nên dành nhờ mọi người :(( )

rox_rook
11-11-2010, 11:22 PM
Hi again,

Để cộng như vậy thì bạn dùng mãng là internal data, ví dụ như đã có một bạn viết rồi. Cái chính là thuật toán thực hiện phép cộng. Khi bạn cộng bằng tay bạn làm thế nào thì trong máy tính nó sẽ ra thế đó. Cộng từ phần tử của mãng lại.
Mình cho bạn cái khung, bạn thử xem sao:


#include <iostream>
#include <vector>

using namespace std;

class hexa
{
hexa()
{

}

const hexa& operator +( const hexa& rhs )
{
for( int i = 0, isize = rhs.num.size(); i < isize; ++i )
{
// handle operation
}
}

private :
vector<char> num;
;

toanoi02020
11-11-2010, 11:34 PM
uhm thanks nhưng mà tới cũng nghĩ tới rồi nhưng mà ngại bắt tay vào làm mà đợi ăn sẵn :d vậy tối mai tớ post code lên nhờ mọi người giúp vậy

langman
12-11-2010, 12:15 AM
spam hi vọng kiếm chút cháo
tớ thử code thế này ko bít có được ko
mong mọi người chỉ bảo

#include <iostream>
using namespace std;

char ctoi(char x)
{
return x>='0'&&x<='9'?x-'0':
x>='a'&&x<='z'?x-'a'+10:
x>='A'&&x<='Z'?x-'A'+10:
NULL;
}
char* sum(char *a,char *b,char *s)
{
for (int i=0,temp=0,ai=strlen(a),bi=strlen(b),n=ai>bi?ai:bi;i<n+1;i++)
{
s[i]=ctoi(ai>i?a[ai-i-1]:'0')+ctoi(bi>i?b[bi-i-1]:'0') +temp;
if (i!=n&&s[i]!=0)
{
temp=s[i]>15;
s[i]=(s[i]%16)["0123456789abcdef"];
s[i+1]=0;
}
}
strrev(s);
return s;
}
void main()
{
char a[100]={},b[100]={},s[101]={};
printf("Input hexadecimal number :");
scanf("%[0-9a-fA-F] %[0-9a-fA-F]",a,b);
printf("%s\n", sum(a,b,s));
system("pause");
}