-
2021-02-13 02:01:23
如下代码:public class Example005 {
public static void main(String[] args) {
System.out.println("out1="
+ Long.toHexString(0x100000000L + 0xcafebabe));
System.out.println("out2="
+ Long.toHexString(0x100000000L + 0xcafebabeL));
}
}
输出结果:out1=cafebabe
out2=1cafebabe
原因分析:
首先要知道的一个问题是,十进制数是依靠前导一元操作符(+/-)来表达正负的。而十六进制、八进制、二进制在计算机中是用补码表示的。补码的优势在于:使用补码,可以将符号位和其它位统一处理;同时,减法也可按加法来处理。另外,两个用补码表示的数相加时,如果最高位(符号位)有进位,则进位被舍弃。在上述程序中,数字 0xcafebabe是一个 int 常量,它的最高位被置位了 ,所以它是一个负数。它等于十进制数值-889275714。
out1执行的这个加法是一种混合类型的计算(mixed-type computation):左操作数是 long 类型的,而右操作数是 int 类型的。为了执行该计算,Java 将int 类型的数值用拓宽原始类型转换提升为一个 long 类型,然后对两个 long 类型数值相加。因为 int 是一个有符号的整数类型,所以这个转换执行的是符合扩展:它将负的 int 类型的数值提升为一个在数值上相等的 long 类型数值。这个加法的右操作数0xcafebabe 被提升为了 long 类型的数值0xffffffffcafebabeL。这个数值之后被加到了左操作数 0x100000000L 上。当作为 int 类型来被审视时, 经过符号扩展之后的右操作数的高 32 位是-1,而左操作数的高 32 位是 1,将这两个数值相加就得到了 0,这也就解释了为什么在out1的前导 1 丢失了。
在out2中,0xcafebabeL使用十六进制字面常亮来表示,避免了有破坏力的符号扩展,所以打印结果也就正确了。
(注:本【java解惑】系列,均是博主阅读《java解惑》原书后,将原书上的讲解和例子部分改编,然后写成博文进行发布的。所有例子均亲自测试通过,并共享在github上。通过这些例子,激励自己,惠及他人。同时,本系列所有博文会同步发布在博主个人微信公众号(搜索“爱题猿”或者“ape_it”),方便大家阅读。如果文中有任何侵犯原作者权利的内容,请及时告知博主,以便及时删除;如果读者对文中的内容有异议或者问题,欢迎通过博客留言或者微信公众号留言等方式共同探讨。)
更多相关内容 -
二进制加法Java实现
2021-03-22 13:24:16二进制整数的Java实现任意两个二进制数(不论在什么位置)相加,只可能出现4种情况。它们是:0+0=01+0=0+1=11+1=10=0+向高一位的进位11+1+1=11=1+向高一位的进位1//整数二进制相加public static String add(String b1,...二进制整数的Java实现
任意两个二进制数(不论在什么位置)相加,只可能出现4种情况。它们是:
0+0=0
1+0=0+1=1
1+1=10=0+向高一位的进位1
1+1+1=11=1+向高一位的进位1
//整数二进制相加
public static String add(String b1, String b2) {
int len1 = b1.length();
int len2 = b2.length();
String s1 = b1;
String s2 = b2;
StringBuffer sb1 = new StringBuffer();
//先将位数较少的二进制高位补零
if(len1 > len2) {
for(int i = 0; i < (len1 - len2); i++) {
sb1.append(0);
}
sb1.append(b2);
s1 = b1;
s2 = sb1.toString();
} else if(len1 < len2) {
for(int j = 0; j < (len2 - len1); j++) {
sb1.append(0);
}
sb1.append(b1);
s1 = sb1.toString();
s2 = b2;
}
//进位
int flag = 0;
StringBuffer sb2 = new StringBuffer();
for(int z = s1.length() - 1; z >= 0; z--) {
//字符’0’的对应的ASCII十进制是48
//分情况判断
if((s1.charAt(z) - 48) == 0 && (s2.charAt(z) - 48) == 0) {
sb2.append(flag);
flag = 0;
continue;
}
if(((s1.charAt(z) - 48) == 0 && (s2.charAt(z) - 48) == 1 && flag == 0) || ((s1.charAt(z) - 48) == 1 && (s2.charAt(z) - 48) == 0 && flag == 0)) {
sb2.append(1);
flag = 0;
continue;
}
if(((s1.charAt(z) - 48) == 0 && (s2.charAt(z) - 48) == 1 && flag == 1) || ((s1.charAt(z) - 48) == 1 && (s2.charAt(z) - 48) == 0 && flag == 1)) {
sb2.append(0);
flag = 1;
continue;
}
if((s1.charAt(z) - 48) == 1 && (s2.charAt(z) - 48) == 1 && flag == 0) {
sb2.append(0);
flag = 1;
continue;
}
if((s1.charAt(z) - 48) == 1 && (s2.charAt(z) - 48) == 1 && flag == 1) {
sb2.append(1);
flag = 1;
}
}
if(flag == 1) {
sb2.append(flag);
}
//倒置
sb2.reverse();
return sb2.toString();
}
测试
public static void main(String[] args) {
System.out.println(add("101", "011"));
System.out.println(add("1001", "1011"));
}
-
字节跳动-算法面试-36进制加法
2021-03-13 20:52:1936进制由0-9,a-z,共36个字符表示,最小为'0'* '0''9'对应十进制的09,'a''z'对应十进制的1035* 例如:'1b' 换算成10进制等于 1 * 36^1 + 11 * 36^0 = 36 + 11 = 47* 要求按照加法规则计算出任意两个36进制正整数的...public class Test36Bin {
/**
* 36进制由0-9,a-z,共36个字符表示,最小为'0'
* '0''9'对应十进制的09,'a''z'对应十进制的1035
* 例如:'1b' 换算成10进制等于 1 * 36^1 + 11 * 36^0 = 36 + 11 = 47
* 要求按照加法规则计算出任意两个36进制正整数的和
* 如:按照加法规则,计算'1b' + '2x' = '48'
*
* 要求:不允许把36进制数字整体转为10进制数字,计算出10进制数字的相加结果再转回为36进制
*
* @param args
*/
public static void main(String [] args) {
String result = addFunWithStr("1b", "2x");
System.out.println("result = " + result);
}
/**
* 获取值
* @param ch
* @return
*/
public static int getIntFromChar(char ch) {
int ret = -1;
if (ch >='0' && ch <= '9') {
ret = ch - '0';
} else if (ch >= 'a' && ch <= 'z') {
ret = (ch - 'a') + 10;
}
return ret;
}
public static String addFunWithStr(String param1, String param2) {
StringBuffer stringBuffer = new StringBuffer();
String symbol = "0123456789abcdefghijklmnopqrstuvwxyz";
int param1Len = param1.length();
int param2Len = param2.length();
int i = param1Len - 1;
int j = param2Len - 1;
if (i < 0 || j < 0) {
return null;
}
int temp = 0;
while (i >= 0 && j >= 0) {
char ch_1 = param1.charAt(i);
char ch_2 = param2.charAt(j);
int v1 = getIntFromChar(ch_1);
int v2 = getIntFromChar(ch_2);
int ret = v1 + v2;
if (ret >= 36) {
int index = ret - 36 + temp;
char sv = symbol.charAt(index);
stringBuffer.append(sv);
temp = 1; //进位
} else {
int index = ret + temp;
char sv = symbol.charAt(index);
stringBuffer.append(sv);
temp = 0;
}
i--;
j--;
}
while (i >= 0) {
char ch_1 = param1.charAt(i);
stringBuffer.append(ch_1);
i--;
}
while (j >= 0) {
char ch_2 = param2.charAt(i);
stringBuffer.append(ch_2);
j--;
}
StringBuffer result = stringBuffer.reverse();
return result.toString();
}
}
-
Java大数加法乘法减法、36进制加法
2022-01-29 17:42:00大数加法 1、是整数; 2、两个数无限大,long都装不下; 3、不能用BigInteger; 4、不能用任何包装类提供的运算方法; 5、两个数都是以字符串的方式提供。 /** * 思路: * 字符串逐位相加,需要进位则进位处理,...
大数加法
1、是整数; 2、两个数无限大,long都装不下; 3、不能用BigInteger; 4、不能用任何包装类提供的运算方法; 5、两个数都是以字符串的方式提供。
/** * 思路: * 字符串逐位相加,需要进位则进位处理,考虑两个问题: * 1、char怎么转换为integer, 减去'0'即可 * 2、怎么处理对应位相加?反转字符串相加,正确处理进位即可, * 这样个位对应个位,十位对应十位,剩余的直接追加 * */ public static String add(String str1, String str2) { char[]arr1 = new StringBuilder(str1).reverse().toString().toCharArray(); char[]arr2 = new StringBuilder(str2).reverse().toString().toCharArray(); int maxlen = arr1.length>arr2.length?arr1.length:arr2.length; int [] newlen = new int[maxlen+1]; for (int i = 0; i < maxlen; i++) { int an1 = i < arr1.length?arr1[i]-'0':0; int an2 = i < arr2.length?arr2[i]-'0':0; newlen[i] = an1+an2; } for (int i = 0; i < newlen.length; i++) { if(newlen[i] >= 10) { newlen[i+1] += newlen[i]/10; newlen[i] %=10; } } StringBuilder ans = new StringBuilder(); for (int i = newlen.length-1; i >=0;i--) { ans.append(newlen[i]); } if(ans.toString().charAt(0)=='0') { return ans.toString().substring(1,ans.length());//去掉开头可能有的0 } return ans.toString(); } public static void main(String[] args) { System.out.println( add("9234","22999999999")); }
大数减法
题目描述
给定两个字符串形式的非负整数 num1 和num2 ,计算它们的差。注意:
num1 和num2 都只会包含数字 0-9
num1 和num2 都不包含任何前导零
你不能使用任何內建 BigInteger 库
两个非负整数相减的结果可能为负。因此,首先比较两个数的大小。
如代码所示,当小减大时,需将两个参数调换一下位置执行减法,在结果前填上负号即可
注意:结果为0时不加负号。
如何比较两个大数的大小呢?
由于是大数,肯定不能直接转成int比较。
我们可以比较两个字符串的长度。
长度更长的字符串,数一定更大;当长度一样的就去比较字典序。
c++版本
bool isLess(string a, string b) { if (a.size() == b.size()) return a < b; return a.size() < b.size(); }
减法操作代码:
string sub(string a, string b) { string res = ""; int borrow = 0; int i = a.size() - 1, j = b.size() - 1; while (i >= 0 || j >= 0) { int x = i >= 0 ? (a[i] - '0') : 0; //字符转整数 int y = j >= 0 ? (b[j] - '0') : 0; //字符转整数 int z = (x - borrow - y + 10) % 10; res += ('0' + z); //整数转成字符 borrow = x - borrow - y < 0 ? 1 : 0; i--, j--; } reverse(res.begin(), res.end()); //删除前导0,注意边界是res.size()-1!!防止当res为"0000"时,删为""的清空 int pos; for (pos = 0; pos < res.size() - 1; pos++) { if (res[pos] != '0') break; } return res.substr(pos); }
主方法:
string subStrings(string num1, string num2) { string res; if (isLess(num1, num2)) { res = sub(num2, num1); if (res != "0") res.insert(0, "-"); } else res = sub(num1, num2); return res; }
Java版本
public boolean isless(String a,String b) //判断两个字符串大小 { if(a.length()==b.length()) if( a.compareTo(b)<0) { return true;} else {return false;} else return a.length()<b.length(); } public String reverse(String s) { //字符串反转 char[]arr = new char[s.length()]; int i = 0,j = s.length()-1; while(i <=j) { arr[i] = s.charAt(j); arr[j] = s.charAt(i); i++; j--; } return new String(arr); } public String sub(String a,String b) {//两个字符串相减 int i = a.length()-1,j=b.length()-1; int borrow=0; String ans=""; while(i>=0||j>=0) { int x = i>=0?(a.charAt(i)-'0'):0; int y = j>=0?(b.charAt(j)-'0'):0; int result = (x-borrow-y+10)%10; ans+=result; borrow = x-borrow-y<0?1:0; i--;j--; } ans=reverse(ans); int ii = 0; for(ii= 0;ii<ans.length();ii++) if(ans.charAt(ii)!='0') break; return ans.substring(ii,ans.length()); } public String mainope(String a,String b) { //用于判断两个字符串哪个大,如果是小的减去大的则在答案前面加符号,且最后的结果转化为字符串输出 String res=""; StringBuilder str= new StringBuilder(); if(isless(a,b)) { res = sub(b,a); if(res!="0") { str.append("-"); str.append(res); return str.toString(); } else return "0"; } else { return sub(a,b); } }
调用:
mainope("1000","8988");//输出-7988
大数乘法
(字符串相乘)
给定两个以字符串形式表示的非负整数 num1 和 num2,返回 num1 和 num2 的乘积,它们的乘积也表示为字符串形式。
注意:不能使用任何内置的 BigInteger 库或直接将输入转换为整数。
public String multiply(String num1, String num2) { LinkedList<Integer>temp = new LinkedList<>(); if(num2.equals("0")||num1.equals("0")) return "0"; int[]ans = new int[num1.length()+num2.length()]; for(int i = num1.length()-1;i>=0;i--) { for(int j = num2.length()-1;j>=0;j--) { int digi1 = num1.charAt(i)-'0'; int digi2 = num2.charAt(j)-'0'; int tot = ans[i+j+1]+digi1*digi2; ans[i+j+1]=tot%10; ans[i+j] += tot/10; } } String ut =""; boolean flag = true; for(int i = 0;i < ans.length;i++) { if(ans[i]==0&&flag) continue; flag = false; if(!flag) ut+=ans[i]; } return ut; }
36进制加法
题目描述
36进制由0-9,a-z,共36个字符表示。要求按照加法规则计算出任意两个36进制正整数的和,如1b + 2x = 48 (解释:47+105=152)
要求:不允许使用先将36进制数字整体转为10进制,相加后再转回为36进制的做法
参考代码c++版
#include <iostream> #include <algorithm> using namespace std; char getChar(int n) { if (n <= 9) return n + '0'; else return n - 10 + 'a'; } int getInt(char ch) { if ('0' <= ch && ch <= '9') return ch - '0'; else return ch - 'a' + 10; } string add36Strings(string num1, string num2) { int carry = 0; int i = num1.size() - 1, j = num2.size() - 1; int x, y; string res; while (i >= 0 || j >= 0 || carry) { x = i >= 0 ? getInt(num1[i]) : 0; y = j >= 0 ? getInt(num2[j]) : 0; int temp = x + y + carry; res += getChar(temp % 36); carry = temp / 36; i--, j--; } reverse(res.begin(), res.end()); return res; } int main() { string a = "1b", b = "2x", c; c = add36Strings(a, b); cout << c << endl; }
Java版
public String reverse(String s) { char[]arr = new char[s.length()]; int i = 0,j = s.length()-1; while(i <=j) { arr[i] = s.charAt(j); arr[j] = s.charAt(i); i++; j--; } return new String(arr); } public char getchar(int n) { if(n<=9) return (char) (n+'0'); else return (char) (n+'a'-10); } public int getint(char ch) { if(ch<='9') return ch-'0'; else return ch-'a'+10; } public String add36(String a,String b) { String ans=""; int len1=a.length()-1,len2=b.length()-1; int carry=0; while(len1>=0||len2>=0) { int x=len1>=0?getint(a.charAt(len1)):0; int y = len2>=0?getint(b.charAt(len2)):0; int result = (x+y+carry)%36; carry = (x+y+carry)/36; ans+=getchar(result); len1--;len2--; } ans = reverse(ans); return ans; }
add36("1de0","8f88")//输出9sm8
-
36进制加法(字节跳动高频面试题/Java写法)
2022-02-23 11:27:05不能转成10进制做36进制加法 -
面试题2:二进制加法(Java版)
2022-04-27 10:46:14题目:输入两个表示二进制的字符串,请计算它们的和,并以 二进制字符串的形式输出。例如,输入的二进制字符串分别 是"11"和"10",则输出"101"。 public static String addBinary(String a, String b) { // 创建一... -
java实现二进制的加法
2021-02-13 01:50:14先看打印结果在看代码比较好理解。结果在最下面的位置。总结:讲解了二进制的按位异域、按位与、左移的运算规则。并通过次3种算法得到2个数...//初始化要执行加法的值System.out.println("===开始二进制运算===");a... -
二进制加法java实现
2021-11-17 19:05:43//大致思路是参照十进制的加法来做,先将两个数末尾对其逐个加逐个进位 public String addBinary(String a, String b) { StringBuffer result = new StringBuffer(); int aLength = a.length() - 1; int ... -
十六进制加法
2021-02-13 02:01:22Problem CTime Limit : 1000/1000ms (Java/Other) Memory Limit : 32768/32768K (Java/Other)Total Submission(s) : 21 Accepted Submission(s) : 6Font: Times New Roman | Verdana | GeorgiaFont Size: ← →Pro..... -
二进制实现加法(java)
2021-12-23 10:56:03二进制位运算实现加法(Java) -
java实现字符串二进制的加法
2021-11-18 19:07:34* @param a 第一个要加的二进制字符串 * @param b 第二个要加的二进制字符串 * @return */ // String:不可变字符序列(操作少量的数据用 String) // StringBuilder:可变字符序列、效率高、线程不安全(单... -
Java编写二进制加法器
2016-12-21 13:37:41最近在学VHDL和verilogHDL。 老师讲到了加法器,我就用Java写了两个程序,一个是普通的逐位加法器,另一个是超前.../*二进制逐位加法器,输入的加数位数一致 不足使用0补齐,进位输入只能为0或1 *@author Frank *@ver -
java 16进制求和示例
2021-04-12 17:13:41java 16进制求和,也就是16进制字节求二进制和,自己写的逻辑有点问题,不能满足需求,故从网上搜了下,满足了需求,代码如下publicclassJinzhi16Util{publicStringmakeChecksum(Stringhexdata){if(hexdata==null||... -
N进制加法
2020-10-07 21:37:07根据十进制加法的原理,我们实现N进制的加法。 依旧是从末位开始逐位相加,并累加进位。 代码: import java.util.*; public class N进制加法 { static String addByBase(String a, String b, int base) { ... -
Java代码 实现两个二进制数的加法
2021-02-28 19:04:06题目要求求两个二进制数的加法算法思路:1、要定义几个参数,carry代表进位,opa代表数组a的元素转换成数字,opb代表数组b的元素转换成数字。sum代表数组的和2、判断两个字符串是否长度相同,如果不同的要从左补齐... -
36进制加法
2021-01-13 19:02:00核心要点:从右往左相加,遇到有进制,carry = 1,保存下次使用,直到遍历完两个字符串,为了处理字符串长度不一的问题,使用三元运算符做处理,字符串长度不足用0补足。 要注意的地方:最后需要单独处理carry,并... -
java 十六进制形式的字符串变量相加计算
2021-08-17 19:31:36先将十六进制形式的字符串变量转换成 Long 类型变量: 》 Long.parseLong(”A1", 16) 》 Long.parseLong(”0F", 16) 再进行相加,再转换成十六进制形式的字符串变量: 》Long.toHexString(Long.parseLong(”A1",... -
Java实现模拟二进制加法
2020-05-18 22:54:18(1) 给定两个只含有0和1字符的字符串,实现二进制加法。如: String str1 = “101” String str2 = “11” 实现binarySum(String s1,String s2),使得输入以上字符时返回字符串"1000"。 拿到这个需求之后 开始是一脸... -
每日一题:36进制加法
2021-07-15 16:27:43暂时只想到了暴力解决法,优化算法空了再思考思考。...要求: 按照加法规则计算出任意两个36进制正整数的和 如: 按照加法规则,计算'1b' + '2x' = '48' """ """ ====================== -*- coding: ut -
从36进制相加认识java的进制机制
2019-03-04 14:33:4036进制的简单实现,也可以扩展成36以下进制。也可以利用java自带API精简代码 public static void main(String[] args) { StringBuilder sb = new StringBuilder(); String num_a = &amp;amp;quot;zz&... -
java 16进制求和
2018-05-05 09:10:50public String makeChecksum (String hexdata) { if (hexdata == null || hexdata.equals( "" )) { return "00" ; } hexdata = hexdata.replaceAll( " " , ...依次得出16进制的和 -
算法---36进制加法
2021-06-22 15:31:08参考链接: 字节高频题补充——36进制加法 36进制由0-9,a-z,共36个字符表示。 要求按照加法规则计算出任意两个36进制正整数的和,如1b + 2x = 48 (解释:47+105=152) 要求:不允许使用先将36进制数字整体转为10... -
java 16进制工具
2021-12-30 17:45:00* 16进制工具类 * 反码: * 一个数是正,则它的反码与原码相同; * 一个数是负,则符号位为1,其余各位是对原码取反 * 补码: * 一个数为正,则它的原码、反码、补码相同 * 一个数为负,则符号位为1,其余...