Ikki katta tamsayılar ko'paytirilishi uchun quyma kerakmi?

Keling, ikkita katta tamsayı bor va ularni ko'paytirishni xohlaysiz.

int a = 150000;
int b = 200000;

Operation 1: [Incorrect] ( Overflows )    
long result = a * b;
Operation 2: [Correct]
long result = (long)a*b;

Natija bilan ta'minlaydigan turdagi o'zgaruvchiga tayinlanish bo'lsa-da, nima uchun quyma kerak?

0
chunki Java avval qadriyatlarni ko'paytiradi va qiymatni tayinlaydi. Bu tayinlangan turga o'xshamaydi
qo'shib qo'ydi muallif Jens, manba
Shubhasiz konvertatsiya keyin ko'paytmasi sodir bo'ladi. Ikki int ni ko'paytirsangiz natijalar int oshib ketadi va undan keyin long
qo'shib qo'ydi muallif UnholySheep, manba

6 javoblar

Ha, quyma kerak.

long int argümanlarının birini yoki ikkalasini chiqarib yubormasangiz, ko'paytirish 32 bitlik operatsiya sifatida amalga oshiriladi. Ko'payish toshib qolsa, natijada natija ga tayinlangan qiymat noto'g'ri bo'ladi.

JLS ("JLS") ma'lumotlariga ko'ra, (" 15.7 .1 ):

Agar butun sonning ko'payishi oshib ketsa, unda natija matematik mahsulotning past darajadagi bitlari bo'lib, ular etarli darajada katta ikkilamchi komplekt formatida namoyon bo'ladi. Natijada, toshib qolsa, natijaning belgisi ikki operand qiymatining matematik mahsuloti belgisi bilan bir xil bo'lmasligi mumkin.

Agar bir yoki har ikkala operandni long ga ko'chirsangiz, u holda 64 soniyali operatsiya sifatida bajariladi va operatsiya bajarilmaydi.

(Operatsiyani long aritmetikasi yordamida amalga oshirishning boshqa usullari mavjud, lekin bunday yozuvlar eng ko'p jirkanchdir.)

3
qo'shib qo'ydi

Java-da int turini diapazoni 2,147,483,648 dan 2,147,483,647 gacha, natijada esa 30000000000 funktsiyasi int tomonidan juda uzoq vaqt ushlab turilmaydi.

2
qo'shib qo'ydi
OP, int ichida saqlanadigan natija juda katta ekanligini biladi.
qo'shib qo'ydi muallif UnholySheep, manba

Sizning holatingizda avval a ni long ga qo'yib, keyin siz ko'paytirishni amalga oshirasiz.

Ushbu operatsiyani ushbu kodni uzoq vaqtdan beri = 1L * a * b ga o'xshaganiga ishonch hosil qilish uchun yangilashingiz mumkin, operatsiya soni sonining uzunligi boshida uzoq vaqt ishlatilsa operatorning ustuvorligiga ehtiyot bo'ling).

Lekin bu ishlamaydi

long result = a * b * 1L

chunki butun sonning ko'payishi birinchi bo'lib bajariladi va butun sonda saqlanadi.

bu yerda birinchi o'ringa tushuntirish uchun javobni ko'ring

1
qo'shib qo'ydi
Kirishingiz uchun rahmat @NamrataBagerwal. Shuni bilib qo'yingki, mening bog'liq javobimni tekshirsangiz, integral va suzuvchi nuqta amaliyoti uchun "o'ziga xos" JLSga ishora qiladi. FYI: ( (long) a * b ) ochish uchun reklama ( 1L * a * b ) ni afzal ko'raman. Bu albatta mening minnatdorligim.
qo'shib qo'ydi muallif AxelH, manba
Operandlardan birini uzoqlashtirish uchun etarli. 1Lni yangi operand sifatida tanitish kerak emas. Batafsil ma'lumot uchun bu yerga murojaat qiling: docs.oracle.com/javase/specs/jls/se7/html/jls-5.html#jls-5.6‌; 2
qo'shib qo'ydi muallif Namrata Bagerwal, manba

Men ketma-ketlikni o'ylayman. Birinchi marta ko'paytirish Ikkinchi topshiriq.

Cheers.

1
qo'shib qo'ydi

Buning sababi, sizda a va b tamsayılar bo'lsa, avval siz ularni uzoqqa (to'qimalarga) almashtirishingiz kerak, aks holda siz ziddiyatli bo'lasiz. Ko'p sonli bitlar (ya'ni 64 bit) bo'lganligi sababli, natijada oddiy int datatype bo'lishi mumkin.

0
qo'shib qo'ydi
qo'shib qo'ydi muallif UnholySheep, manba
Ha, men uni xato deb yozganim uchun afsusdaman. Tuzatish uchun rahmat :)
qo'shib qo'ydi muallif Ramesh Kumar, manba

Har qanday arifmetik operatsiyani bajarishda operatorlarning ustunligini bilish kerak. Belgilash operatori eng kam ahamiyatga ega, shuning uchun natija avval hisoblanib, unga berilgan o'zgaruvchiga tayinlanadi, shuning uchun Java-ni hisoblashda eng yuqori bayt saqlashga ega bo'lgan o'zgarmaydigan turdagi xotira baytlarini ajratadi. Masalan,

  • int * int hisoblangan natijalar int
  • da saqlanadi
  • int * float hisoblangan natijalar floatda saqlanadi
  • float * ikkilik hisoblangan natijalar er-xotin
  • da saqlanadi
  • int * float * ikkilik hisoblangan natijalar er-xotin
  • da saqlanadi

Shunday qilib, sizning namunangizda hisoblangan natijalar int ichida saqlanadi va faqatgina belgilash sodir bo'ladi.

0
qo'shib qo'ydi
float * double natijani double ga saqlaydi: docs.oracle.com/javase/specs/jls/se7/html/jls-5.html#jls-5.6‌; 2 "Agar ikkala operand ikkilik tursa, ikkinchisi ikki marta aylanadi."
qo'shib qo'ydi muallif UnholySheep, manba
Ha, siz haqsiz, u typo edi.
qo'shib qo'ydi muallif Shoban Sundar, manba