[C] 纯文本查看 复制代码
int sub_ip_dp(char * str1, int dot_pos1, int i_qty1, int d_qty1,
char * str2, int dot_pos2, int i_qty2, int d_qty2,
char * str3, int str3_array_size, int * offset);
/* sub_ip_dp() return 1 if no error, -1 if sub error (str1 < str2), 0 if other errors.
* sub integral part and decimal part (str3 = str1 - str2)
* dot_pos: index of str where '.' located for decimal number
* or '\0' located for integral number.
* i_qty: integral number quantity (integral part length)
* d_qty: decimal number quantity (decimal part length)
* str3: array to store result
* str3_array_size: array size
* offset: result will start from here (this function write result from tail to head)
*/
int main(void) //testing
{
char * s1 = "0";
char * s2 = "99999999999999999999";
char * s3 = ".00000000000000000001";
char * s4 = "1.00";
char * s5 = "3.14159";
char * s6 = "0003.14159000";
char * s7 = "9999999999.9999999999";
char str[128];
int i, r;
r = sub_ip_dp(s1, 1, 1, 0, s2, 20, 20, 0, str, 128, &i);
if (r == 1)
printf("\nreturn %d, offset = %d,\n%s - %s = %s\n", r, i, s1, s2, str + i);
else {
r = sub_ip_dp(s2, 20, 20, 0, s1, 1, 1, 0, str, 128, &i);
printf("\nreturn %d, offset = %d,\n%s - %s = -%s\n", r, i, s1, s2, str + i);
}
r = sub_ip_dp(s2, 20, 20, 0, s3, 0, 0, 20, str, 128, &i);
if (r == 1)
printf("\nreturn %d, offset = %d,\n%s - %s = %s\n", r, i, s2, s3, str + i);
else {
r = sub_ip_dp(s3, 0, 0, 20, s2, 20, 20, 0, str, 128, &i);
printf("\nreturn %d, offset = %d,\n%s - %s = -%s\n", r, i, s2, s3, str + i);
}
r = sub_ip_dp(s3, 0, 0, 20, s4, 1, 1, 2, str, 128, &i);
if (r == 1)
printf("\nreturn %d, offset = %d,\n%s - %s = %s\n", r, i, s3, s4, str + i);
else {
r = sub_ip_dp(s4, 1, 1, 2, s3, 0, 0, 20, str, 128, &i);
printf("\nreturn %d, offset = %d,\n%s - %s = -%s\n", r, i, s3, s4, str + i);
}
r = sub_ip_dp(s4, 1, 1, 2, s5, 1, 1, 5, str, 128, &i);
if (r == 1)
printf("\nreturn %d, offset = %d,\n%s - %s = %s\n", r, i, s4, s5, str + i);
else {
r = sub_ip_dp(s5, 1, 1, 5, s4, 1, 1, 2, str, 128, &i);
printf("\nreturn %d, offset = %d,\n%s - %s = -%s\n", r, i, s4, s5, str + i);
}
r = sub_ip_dp(s5, 1, 1, 5, s6, 4, 4, 8, str, 128, &i);
if (r == 1)
printf("\nreturn %d, offset = %d,\n%s - %s = %s\n", r, i, s5, s6, str + i);
else {
r = sub_ip_dp(s6, 4, 4, 8, s5, 1, 1, 5, str, 128, &i);
printf("\nreturn %d, offset = %d,\n%s - %s = -%s\n", r, i, s5, s6, str + i);
}
r = sub_ip_dp(s6, 4, 4, 8, s7, 10, 10, 10, str, 128, &i);
if (r == 1)
printf("\nreturn %d, offset = %d,\n%s - %s = %s\n", r, i, s6, s7, str + i);
else {
r = sub_ip_dp(s7, 10, 10, 10, s6, 4, 4, 8, str, 128, &i);
printf("\nreturn %d, offset = %d,\n%s - %s = -%s\n", r, i, s6, s7, str + i);
}
return 0;
}
int sub_ip_dp(char * str1, int dot_pos1, int i_qty1, int d_qty1,
char * str2, int dot_pos2, int i_qty2, int d_qty2,
char * str3, int str3_array_size, int * offset)
{
//return 1 if no error, -1 if sub error (str1 < str2), 0 if other errors.
char * p1 = str1 + dot_pos1; // p1 is a pointer to '.' or '\0' of str1
char * p2 = str2 + dot_pos2; // p2 is a pointer to '.' or '\0' of str2
int i = str3_array_size; // i is an index of str3, copy to *offset finally
char borrow = '0'; // borrow is a borrow
char c1, c2, c3; // c1, c2 and c3 are temp chars
int k, j; // k and j are temp index
// set '\0' at the end of str3
if (--i >= 0)
str3[i] = '\0';
else
return 0; //Error: insufficient space in str3
// sub decimal part: from tail to head
k = (d_qty1 > d_qty2) ? d_qty1 : d_qty2;
while (k > 0)
{
c1 = (k > d_qty1) ? '0' : p1[k];
c2 = (k > d_qty2) ? '0' : p2[k];
if (0 == dec_char_sub(borrow, c1, c2, &borrow, &c3))
return 0; //Error: return error from dec_char_add()
if (--i >= 0)
str3[i] = c3;
else
return 0; //Error: insufficient space in str3
if (str3[i+1] == '\0' && str3[i] == '0')
i++; //ignore '0' in the end of decimal
--k;
}
// put a '.' in the string
if (str3[i] != '\0')
{
if (--i >= 0)
str3[i] = '.';
else
return 0; //Error: insufficient space in str3
}
// sub integral part: from tail to head
k = 1;
j = (i_qty1 > i_qty2) ? i_qty1 : i_qty2;
while (k <= j)
{
c1 = (k > i_qty1) ? '0' : p1[-k];
c2 = (k > i_qty2) ? '0' : p2[-k];
if (0 == dec_char_sub(borrow, c1, c2, &borrow, &c3))
return 0; //Error: return error from dec_char_add()
if (--i >= 0)
str3[i] = c3;
else
return 0; //Error: insufficient space in str3
++k;
}
// consider borrow after last dec_char_sub()
if (borrow == '1')
return -1; //Error: str1 is smaller than str2, it's not allowed
//you should switch str1 and str2
//try again: - (str2 - str1)
// ignore all begining '0' in the string
while (str3[i] == '0')
++i;
// add a '0' if start with a '.'
if (str3[i] == '.')
{
if (--i >= 0)
str3[i] = '0';
else
return 0; //Error: insufficient space in str3
}
// add a '0' if empty string
if (str3[i] == '\0')
{
if (--i >= 0)
str3[i] = '0';
else
return 0; //Error: insufficient space in str3
}
// set *offset for str3
*offset = i;
return 1; //Done
}