最近看剑指offer的时候,看到c语言操作大数,于是就想用java来写写大数,小伙伴们都表示看不懂,
java有强大的BigInteger和BigDecimal类来支持大数的操作,可是,咸的蛋疼的人总是有的。
目前只完成了加减乘。
java代码
<span style="font-size:18px;">import java.util.Arrays;
public class Test {
// 将字符串转成整形数组
static int[] StringToArray(String s) {
int[] a = new int[s.length()];
for (int i = 0; i < s.length(); i++) {
a[i] = Integer.parseInt(s.substring(s.length() - i - 1, s.length()
- i));
}
return a;
}
// 大数加法
static int[] bigDataAdd(int[] a, int[] b) {
if (a.length < b.length) {
int[] temp = a;
a = b;
b = temp;
}
int len = a.length;
// 多申请一位,存放进位
int[] c = new int[len + 1];
int flag = 0;// 判断是否进位
for (int i = 0; i < b.length; i++) {
c[i] = (a[i] + b[i] + flag) % 10;
flag = (a[i] + b[i] + flag) / 10;
}
if (a.length == b.length && flag != 0) {
c[len] = flag;
} else {
for (int i = b.length; i < a.length; i++) {
c[i] = (a[i] + flag) % 10;
flag = (a[i] + flag) / 10;
}
if (flag == 1) {
c[len] = 1;
}
}
return c;
}
// 加法打印结果
static void printResult1(int[] result) {
// 判断首位是否为0,为0不输出,不为0正常输出
if (result[result.length - 1] == 0) {
for (int i = result.length - 2; i >= 0; i--) {
System.out.print(result[i]);
}
} else {
for (int i = result.length - 1; i >= 0; i--) {
System.out.print(result[i]);
}
}
}
// //将两个数组搞成等长的
// static void equalLength(int[] a,int[] b){
// int len = (a.length>b.length)?a.length:b.length;
// a=Arrays.copyOf(a, len);
// b=Arrays.copyOf(b, len);
// // System.out.println(a.length+".."+b.length);
// }
// 大数减法:符号暂时没完成
static int[] bigDataSubtract(int[] a, int[] b) {
// 将a,b弄成同样长
int len = (a.length > b.length) ? a.length : b.length;
a = Arrays.copyOf(a, len);
b = Arrays.copyOf(b, len);
// System.out.println(a.length + ".." + b.length);
int[] c = new int[len + 1];
// 退位的标志位
int flag = 0;
for (int i = 0; i < len; i++) {
c[i] = ((a[i] - flag) - b[i] + 10) % 10;
// System.out.print(c[i] + "...");
flag = (a[i] - flag) - b[i] >= 0 ? 0 : 1;
}
// System.out.println("c[len]=" + c[len]);
if (flag == 0)
return c;
if (flag == 1) {
// c[len] = 45;// 负号的int值为45
return bigDataSubtract(b, a);
}
return c;
}
// 减法打印结果
static void printResult2(int[] result) {
System.out.println((char) result[result.length - 1]);
if(result[result.length-2]==0){
for (int i = result.length - 3; i >= 0; i--) {
System.out.print(result[i]);
}
}else{
for (int i = result.length - 2; i >= 0; i--) {
System.out.print(result[i]);
}
}
}
// 乘法
static int[] multiply(int a[], int b[]) {
// 实现数组交换
if (a.length < b.length) {
int[] temp = a;
a = b;
b = temp;
}
int c[] = new int[a.length + b.length];
int flag = 0;
for (int j = 0; j < b.length; j++) {
for (int i = 0; i < a.length; i++) {
c[i + j] += a[i] * b[j];
}
}
for (int i = 0; i < c.length; i++) {
int temp = c[i];
c[i] = (temp + flag) % 10;
flag = (temp + flag) / 10;
// System.out.println(c[i]);
}
return c;
}
//乘法打印
static void printResult3(int[] result) {
// System.out.println(result.length );
System.out.println();
if(result[result.length-1]!=0){
for (int i = result.length-1; i >= 0; i--) {
System.out.print(result[i]);
}
}else{
for (int i = result.length-2; i >= 0; i--) {
System.out.print(result[i]);
}
}
}
public static void main(String[] args) {
int[] a = StringToArray("1800");
int[] b = StringToArray("1300");
int[] c1 = bigDataAdd(a, b);
printResult1(c1);
int[] c2 = bigDataSubtract(a, b);
printResult2(c2);
int[] c3 = multiply(a, b);
printResult3(c3);
}
}</span>
<span style="font-size:18px;">
</span>
BigInteger类实现大数操作
<span style="font-size:18px;">//java太强大了</span>
<span style="font-size:18px;">import java.math.BigInteger;
class Test1{
//加
static void add(BigInteger bigInteger1,BigInteger bigInteger2){
bigInteger1=bigInteger1.add(bigInteger2);
System.out.println(bigInteger1);
}
//减
static void subtract(BigInteger bigInteger1,BigInteger bigInteger2){
bigInteger1=bigInteger1.subtract(bigInteger2);
System.out.println(bigInteger1);
}
//乘
static void multiply(BigInteger bigInteger1,BigInteger bigInteger2){
bigInteger1=bigInteger1.multiply(bigInteger2);
System.out.println(bigInteger1);
}
//除
static void divide(BigInteger bigInteger1,BigInteger bigInteger2){
bigInteger1=bigInteger1.divide(bigInteger2);
System.out.println(bigInteger1);
}
//取反
static void negate(BigInteger bigInteger1){
bigInteger1=bigInteger1.negate();
System.out.println(bigInteger1);
}
//阶乘
static void pow(BigInteger bigInteger1,int n){
bigInteger1=bigInteger1.pow(n);
System.out.println(bigInteger1);
}
//取模
static void remainder(BigInteger bigInteger1,BigInteger bigInteger2){
bigInteger1 = bigInteger1.remainder(bigInteger2);
System.out.println(bigInteger1);
}
public static void main(String[] args)throws Exception{
BigInteger bigInteger1=new BigInteger("123214325345424");
BigInteger bigInteger2=new BigInteger("5358038503535");
add(bigInteger1,bigInteger2);
subtract(bigInteger1,bigInteger2);
multiply(bigInteger1,bigInteger2);
divide(bigInteger1,bigInteger2);
negate(bigInteger1);
pow(bigInteger1,10);
remainder(bigInteger1,bigInteger2);
}
}</span>
<strong><span style="font-size:18px;">c语言代码</span></strong>
<strong><span style="font-size:18px;"></span></strong><pre name="code" class="plain">#include<stdio.h>
#include <string.h>
#define M 10
//大数加法
void add(char s1[],char s2[])//参数为两个字符数组
{
//初始化
int num1[M]={0};
int num2[M]={0};
int i,j;
int len1=strlen(s1);
int len2=strlen(s2);
for(i=len1-1,j=0;i>=0;i--)
{
num1[j++]=s1[i]-'0';
}
for(i=len2-1,j=0;i>=0;i--)
{
num2[j++]=s2[i]-'0';
}
for(i=0;i<M;i++)
{
num1[i]=num1[i]+num2[i];
if(num1[i]>9)
{
num1[i]=num1[i]-10;
num1[i+1]++;
}
}
//打印输出
//找到第一个不是0的位置
for(i=M-1;(i>=0)&&(num1[i]==0);i--);
if(i>=0)
{
for(;i>=0;i--)
printf("%d",num1[i]);
}
else
printf("0\n");
}
int compare(char* s1,char* s2)
{
int sl1=strlen(s1);
int sl2=strlen(s2);
if(sl1>sl2)return 1;
else if(sl1<sl2)return -1;
else{
int i=0;
while(i<sl1-1){
if(s1[i]>s2[i]){
return 1;
}else if(s1[i]<s2[i]){
return -1;
}else{
i++;
}
}
return 0;
}
}
//大数减法
void subtract(char s1[],char s2[]){
//初始化
int num1[M]={0};
int num2[M]={0};
int i,j;
int len1=strlen(s1);
int len2=strlen(s2);
for(i=len1-1,j=0;i>=0;i--){
num1[j++]=s1[i]-'0';
}
for(i=len2-1,j=0;i>=0;i--){
num2[j++]=s2[i]-'0';
}
int flag=compare(s1,s2);
if(flag>=0){
for(i=0;i<M;i++){
num1[i]=num1[i]-num2[i];
if(num1[i]<0)
{
num1[i]=num1[i]+10;
num1[i+1]--;
}
}
for(i=M-1;(i>=0)&&(num1[i]==0);i--);
if(i>=0)
{
for(;i>=0;i--)
printf("%d",num1[i]);
}
else
printf("0\n");
}
else{
for(i=0;i<M;i++){
num2[i]=num2[i]-num1[i];
// printf("%d",num2[i]);
if(num2[i]<0)
{
num2[i]=num2[i]+10;
num2[i+1]--;
}
}
for(i=M-1;(i>=0)&&(num2[i]==0);i--);
printf("-");
if(i>=0)
{
for(;i>=0;i--)
printf("%d",num2[i]);
}
else
printf("0\n");
}
}
void Multiply(char s1[],char s2[])
{
//初始化
int num1[M]={0};
int num2[M]={0};
int num3[M]={0};
int i,j;
int len1=strlen(s1);
int len2=strlen(s2);
for(i=len1-1,j=0;i>=0;i--){
num1[j++]=s1[i]-'0';
}
for(i=len2-1,j=0;i>=0;i--){
num2[j++]=s2[i]-'0';
}
for(j=0;j<len2;j++){
for(i=0;i<len1;i++){
num3[i+j]+=num1[i]*num2[j];
}
}
// printf("%d\n",num3[0]);
int flag=0;
for(i=0;i<M;i++){
int p=num3[i];
num3[i]=(p+flag)%10;
flag=(p+flag)/10;
}
for(i=M-1;(i>=0)&&(num3[i]==0);i--){}
if(i>=0)
{
for(;i>=0;i--){
printf("%d",num3[i]);
}
}
else
//没有打印0
printf("0\n");
}
<span style="color:#ff0000;">//注意定义char类型的字符串方式</span>
void main()
{
// char s1[]={'1','2','\0'};
char s1[]="10000";
char s2[]="982323";
Multiply(s1,s2);
}
总结:java减法一直是困扰我的,因为符号判断很难,策略:1.看长度,但如果长度相同呢,2.只能先运行一遍再判断最高位是否退位了,退位了加负号,这么简单的还是没完成。