30/09/2018, 16:45
Bignum: nhờ sửa lỗi phát sinh trong C++
// BIGNUM.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include <iostream>
using namespace std;
//Khai báo hằng
#define MAXDIGITS 100 /* maximum length */
#define PLUS 1 /* positive sign bit */
#define MINUS -1 /* negative sign bit */
//Khai báo cấu trúc
typedef struct {
char digits[MAXDIGITS]; /* the number */
int signbit; /* PLUS or MINUS */
int lastdigit; /*index of high-order digit*/
}bignum;
// khai báo hàm
void print_bignum(bignum n);
void scan_bignum(bignum &n);
void zero_justify(bignum &n);
void add_bignum(bignum &a, bignum &b, bignum &c);
void subtract_bignum(bignum a, bignum b, bignum &c);
int compare_bignum(bignum &a, bignum &b);
//Một số hàm xử lý
void print_bignum(bignum n)
{
int i;
if (n.signbit == MINUS) cout << "-";
for (i = n.lastdigit; i >= 0; i--)
cout << int(n.digits[i]); // ép kiểu để ko ra ký tự lạ
//cout <<endl;
}
int kiemtra(char s[]){
//ktra ký tự đầu
if (s[0] != '-' && !isdigit(s[0]))
return 0;
//ktra các ký tự tiếp theo
int len = strlen(s);
for (int i = 1; i<len; i++)
if (!isdigit(s[i])) return 0;
//không phát hiện vi phạm
return 1;
}
void scan_bignum(bignum &n)
{
//B1: Nhập chuỗi
char temp[256];
cin.getline(temp, 256);
//B2: Kiểm tra
if (!kiemtra(temp)){ //không hợp lệ
//gán bignum = 0
n.signbit = PLUS;
n.lastdigit = 0;
n.digits[0] = 0;
}
else { //hợp lệ. B3: chuyển thành số bignum
//xét 2 trường hợp
if (temp[0] != '-'){ //số dương
n.signbit = PLUS;
n.lastdigit = strlen(temp) - 1;
for (int i = 0; i <= n.lastdigit; i++)
n.digits[i] = temp[n.lastdigit - i] - 48;
}
else { //số âm
n.signbit = MINUS;
n.lastdigit = strlen(temp) - 2;
for (int i = 0; i <= n.lastdigit; i++)
n.digits[i] = temp[n.lastdigit + 1 - i] - 48;
}
}
}
// loại bỏ những số không vô nghĩa
/**/
void zero_justify(bignum &n)
{
while ((n.lastdigit > 0) && (n.digits[n.lastdigit] == 0))
n.lastdigit--;
if ((n.lastdigit == 0) && (n.digits[0] == 0))
n.signbit = PLUS; /* hack to avoid -0 */
}
//
/**/
int max(int a, int b)
{
if (a > b) return a;
return b;
}
void add_bignum(bignum &a, bignum &b, bignum &c)
{
int carry; /* carry digit */
int i; /* counter */
//initialize_bignum(c); // khởi gán cho các chữ số bằng 0
if (a.signbit == b.signbit) c.signbit = a.signbit;
else
{ // cộng 2 số trái dấu
if (a.signbit == MINUS)
{
a.signbit = PLUS;
subtract_bignum(b, a, c);
a.signbit = MINUS;
}
else
{
b.signbit = PLUS;
subtract_bignum(a, b, c);
b.signbit = MINUS;
}
return;
}
c.lastdigit = max(a.lastdigit, b.lastdigit) + 1;
// điều chỉnh a,b
for (i = a.lastdigit + 1; i <= c.lastdigit; i++)
a.digits[i] = 0;
for (i = b.lastdigit + 1; i <= c.lastdigit; i++)
b.digits[i] = 0;
carry = 0;
for (i = 0; i <= (c.lastdigit); i++) {
c.digits[i] = (char)
(carry + a.digits[i] + b.digits[i]) % 10;
carry = (carry + a.digits[i] + b.digits[i]) / 10;
}
zero_justify(c);
}
//
void subtract_bignum(bignum a, bignum b, bignum &c)
{
int borrow; /* anything borrowed? */
int v; /* placeholder digit */
int i; /* counter */
if ((a.signbit == MINUS) || (b.signbit == MINUS)) {
b.signbit = -1 * b.signbit;
add_bignum(a, b, c);
b.signbit = -1 * b.signbit;
return;
}
if (compare_bignum(a, b) == PLUS)
{
subtract_bignum(b, a, c);
c.signbit = MINUS;
return;
}
c.lastdigit = max(a.lastdigit, b.lastdigit);
for (i = a.lastdigit + 1; i <= c.lastdigit; i++)
a.digits[i] = 0;
for (i = b.lastdigit + 1; i <= c.lastdigit; i++)
b.digits[i] = 0;
borrow = 0;
for (i = 0; i <= (c.lastdigit); i++) {
v = (a.digits[i] - borrow - b.digits[i]);
if (a.digits[i] > 0)
borrow = 0;
if (v < 0) {
v = v + 10;
borrow = 1;
}
c.digits[i] = (char)v % 10;
}
zero_justify(c);
}
//
int compare_bignum(bignum &a, bignum &b)
{
int i; /* counter */
if ((a.signbit == MINUS) && (b.signbit == PLUS)) return(PLUS);
if ((a.signbit == PLUS) && (b.signbit == MINUS)) return(MINUS);
if (b.lastdigit > a.lastdigit) return (PLUS * a.signbit);
if (a.lastdigit > b.lastdigit) return (MINUS * a.signbit);
for (i = a.lastdigit; i >= 0; i--)
{
if (a.digits[i] > b.digits[i])
return(MINUS * a.signbit);
if (b.digits[i] > a.digits[i])
return(PLUS * a.signbit);
}
return(0);
}
void digit_shift(bignum n, int d) /* multiply n by 10ˆd */
{
int i; /* counter */
if ((n.lastdigit == 0) && (n.digits[0] == 0)) return;
for (i = n.lastdigit; i >= 0; i--)
n.digits[i + d] = n.digits[i];
for (i = 0; i<d; i++) n.digits[i] = 0;
n.lastdigit = n.lastdigit + d;
}
void multiply_bignum(bignum &a, bignum &b, bignum &c)
{
bignum row; /* represent shifted row */
bignum tmp; /* placeholder bignum */
int i, j; /* counters */
//initialize_bignum(c);
row = a;
for (i = 0; i <= b.lastdigit; i++)
{
for (j = 1; j <= b.digits[i]; j++)
{
add_bignum(c, row, tmp);
c = tmp;
}
digit_shift(row, 1);
}
c.signbit = a.signbit * b.signbit;
zero_justify(c);
}
void divide_bignum(bignum a, bignum b, bignum &c)
{
bignum row; /* represent shifted row */
bignum tmp; /* placeholder bignum */
int asign, bsign; /* temporary signs */
int i, j; /* counters */
//initialize_bignum(c);
c.signbit = a.signbit * b.signbit;
asign = a.signbit;
bsign = b.signbit;
a.signbit = PLUS;
b.signbit = PLUS;
//initialize_bignum(&row);
//initialize_bignum(&tmp);
c.lastdigit = a.lastdigit;
for (i = a.lastdigit; i >= 0; i--) {
digit_shift(row, 1);
row.digits[0] = a.digits[i];
c.digits[i] = 0;
while (compare_bignum(row, b) != PLUS) {
c.digits[i] ++;
subtract_bignum(row, b, tmp);
row = tmp;
}
}
zero_justify(c);
a.signbit = asign;
b.signbit = bsign;
}
int _tmain(int argc, _TCHAR* argv[])
{
bignum n;
bignum row;
bignum tmp;
cout << "nhap vao so lon:";
scan_bignum(n);
cout << "so lon vua nhap:";
print_bignum(n);
cout << endl;
/////////////////////////////////////
///////////////////////////////
bignum a, b, c;
cout << "nhap vao a=";
scan_bignum(a);
cout << "nhap vao b=";
scan_bignum(b);
subtract_bignum(a, b, c);
cout << "a+b=";
print_bignum(c);
cout << endl;
cout << "a-b=";
print_bignum(c);
cout << endl;
multiply_bignum(a, b, c);
cout << "a*b=";
print_bignum(c);
cout << endl;
///////////////////////////////
return 0;
}
Bài liên quan
lỗi gì vậy bạn? bạn nêu chi tiết được không?
Hàm
multiply_bignum
của bạn bị sai. Mình sửa lại và chia thành 2 hàmmultiply_int
vàmultiply_bignum
digit_shift(bignum n, int d)
của bạn truyền bằng value nên không có tác dụng. Sửa lại:digit_shift(bignum&,int d)
hi. mình sửa đc rồi ,nhung ham chia thì ko ra, nó bị sai ở vòng lặp nhưng mình ko bít chỗ nào hết