কেন int i = 1024 * 1024 * 1024 * 1024 ত্রুটি ছাড়াই সংকলন করে?


152

এর সীমা int-2147483648 থেকে 2147483647 পর্যন্ত।

যদি আমি ইনপুট

int i = 2147483648;

তারপরেই ग्रहणটি "2147483648" এর আওতায় একটি লাল আন্ডারলাইন প্রম্পট করবে।

তবে আমি যদি এটি করি:

int i = 1024 * 1024 * 1024 * 1024;

এটি জরিমানা সংকলন করবে।

public class Test {
    public static void main(String[] args) {        

        int i = 2147483648;                   // error
        int j = 1024 * 1024 * 1024 * 1024;    // no error

    }
}

সম্ভবত এটি জাভাতে একটি প্রাথমিক প্রশ্ন, তবে দ্বিতীয় রূপটি কেন ত্রুটি সৃষ্টি করে তা আমার কোনও ধারণা নেই।


10
এমনকি সংকলকটি অপ্টিমাইজেশান হিসাবে গণনাটিকে একটি একক মান হিসাবে "ধসে" দেবে, ফলাফলটি ওভারফ্লো হতে পারে যদি না তবে কোনও অপ্টিমাইজেশন প্রোগ্রামের আচরণ পরিবর্তন করতে পারে না।
হট লিকস

1
এবং এটি ব্যাখ্যা করতে পারে না2147483648 : এই আক্ষরিক কোনও ধারণা নেই।
সাগ্ররেট

1
এবং জাভা পূর্ণসংখ্যার ওভারফ্লো সম্পর্কে প্রতিবেদন করে না - ক্রিয়াকলাপটি নিঃশব্দে "ব্যর্থ"।
হট লিক্স

5
@ জ্যাকবক্রল: সি # চেক-নেস চালু আছে কিনা তা বিবেচনা না করে এটিকে ত্রুটি হিসাবে রিপোর্ট করবে; সমস্ত ধরণের গণনা যা কেবলমাত্র ধ্রুবক এক্সপ্রেশন নিয়ে থাকে তা চেক করা অঞ্চলে না থাকলে স্বয়ংক্রিয়ভাবে পরীক্ষা করা হয়।
এরিক লিপার্ট

54
আমি আপনাকে স্ট্যাকওভারফ্লোতে "কেন নয়" প্রশ্ন জিজ্ঞাসা করতে নিরুৎসাহিত করি; তারা উত্তর দেওয়া কঠিন। একটি "কেন নয়" প্রশ্নটি অনুমান করে যে পৃথিবীর স্পষ্টতই এমন একটি উপায় হওয়া উচিত যা এটি নয় এবং এটি সেভাবে হওয়ার জন্য একটি যুক্তিসঙ্গত কারণ হওয়া দরকার। এই অনুমান প্রায় কার্যকর হয় না। আরও সুনির্দিষ্ট প্রশ্নটি হ'ল "স্পেসিফিকেশনের কোন বিভাগটি বর্ণনা করে যে ধ্রুবক পূর্ণসংখ্যার গণনা করা হয় কীভাবে?" বা "জাভাতে পূর্ণসংখ্যা ওভারফ্লোগুলি কীভাবে পরিচালনা করা হয়?"
এরিক লিপার্ট

উত্তর:


233

এই বিবৃতিতে কোনও ভুল নেই; আপনি কেবল 4 সংখ্যাগুলি গুণন করছেন এবং এটি কোনও পূর্বনির্ধারিত স্থানে নিযুক্ত করছেন, সেখানে কেবল একটি ওভারফ্লো হবে। এটি একটি একক আক্ষরিক অর্পণ করার চেয়ে পৃথক , যা সংকলন-সময়ে সীমাবদ্ধভাবে পরীক্ষা করা হবে।

এটি সীমার বাইরে থাকা আক্ষরিক যা ত্রুটির কারণ হয়ে থাকে, নিয়োগের জন্য নয় :

System.out.println(2147483648);        // error
System.out.println(2147483647 + 1);    // no error

বিপরীতে একটি longআক্ষরিক জরিমানা সংকলন করবে:

System.out.println(2147483648L);       // no error

মনে রাখবেন যে, আসলে, ফলাফলের হয় এখনও কম্পাইল-সময়ে নির্ণিত কারণ 1024 * 1024 * 1024 * 1024একটি নয় ধ্রুবক অভিব্যক্তি :

int i = 1024 * 1024 * 1024 * 1024;

হয়ে:

   0: iconst_0      
   1: istore_1      

লক্ষ্য করুন যে ফলাফলটি ( 0) কেবল লোড এবং সংরক্ষণ করা হয় এবং কোনও গুণ ঘটে না।


জেএলএস §3.10.1 থেকে (মন্তব্যগুলিতে এটি প্রকাশের জন্য @ ক্রিসকে ধন্যবাদ):

দশমিক আক্ষরিক ধরণের (2 31 ) এর intচেয়ে বড় , বা দশমিক আক্ষরিক যদি আনারি মাইনাস অপারেটরের ( §15.15.4 ) অপারেন্ড হিসাবে প্রদর্শিত না হয় তবে এটি একটি সংকলন-সময় ত্রুটি ।21474836482147483648


12
এবং গুণটির জন্য জেএলএস বলে, যদি কোনও পূর্ণসংখ্যার গুণটি ওভারফ্লো হয় তবে ফলাফলটি গাণিতিক পণ্যের নিম্ন-অর্ডার বিট হিসাবে কিছু পর্যাপ্ত পরিমাণে দুটি বড় পরিপূরক বিন্যাসে উপস্থাপিত হয়। ফলস্বরূপ, যদি ওভারফ্লো হয়, তবে ফলাফলটির সাইন দুটি অপরেন্ড মানগুলির গাণিতিক পণ্যের চিহ্ন হিসাবে একই নাও হতে পারে।
ক্রিস কে

3
দুর্দান্ত উত্তর। কিছু লোকের মনে হয় যে ওভারফ্লো একরকম ত্রুটি বা ব্যর্থতা, তবে তা নয়।
ওয়াউটার লিভেন্সস

3
@ iowatiger08 ভাষা শব্দার্থবিজ্ঞানগুলি জেএলএস দ্বারা বর্ণিত হয়েছে, যা জেভিএম থেকে স্বতন্ত্র (সুতরাং আপনি কোন জেভিএম ব্যবহার করেন তা বিবেচনা করা উচিত নয়)।
আর্শাজি

4
@WouterLievens, ওভারফ্লো হয় সাধারণত একটি "ব্যতিক্রমী" অবস্থা, যদি না একটি সরাসরি ত্রুটি শর্ত। এটি সীমাবদ্ধ-নির্ভুল গণিতের ফল, যা গণিত করার সময় বেশিরভাগ লোক স্বজ্ঞাতভাবে ঘটবে বলে আশা করে না। কিছু ক্ষেত্রে, যেমন -1 + 1, এটি নিরীহ; তবে 1024^4এটি সম্পূর্ণ অপ্রত্যাশিত ফলাফল সহ লোককে অন্ধ করে দিতে পারে, তারা যা দেখার প্রত্যাশা করবে তার থেকে দূরে। আমি মনে করি ব্যবহারকারীর জন্য কমপক্ষে একটি সতর্কতা বা নোট থাকা উচিত, এবং নিঃশব্দে এড়ানো উচিত নয়।
ফিল পেরি

1
@ iowatiger08: int এর আকার নির্ধারিত; এটি JVM এর উপর নির্ভর করে না । জাভা সি নয়
মার্টিন শ্রাইডার

43

1024 * 1024 * 1024 * 1024এবং 2147483648জাভাতে একই মান নেই।

প্রকৃতপক্ষে, জাভাতে 2147483648 ভ্যালু (যদিও 2147483648Lতা) নেই। সংকলক আক্ষরিকভাবে এটি কী তা বা কীভাবে এটি ব্যবহার করতে পারে তা জানে না। সুতরাং এটি whines।

1024জাভা একটি বৈধ int- এ, এবং একটি বৈধ intঅন্য বৈধ দ্বারা গুন int, সবসময় একটি বৈধ int। এমনকি যদি এটি একই মান না হয় যা আপনি স্বজ্ঞাতভাবে আশা করবেন কারণ গণনাটি উপচে পড়বে।

উদাহরণ

নিম্নলিখিত কোড নমুনা বিবেচনা করুন:

public static void main(String[] args) {
    int a = 1024;
    int b = a * a * a * a;
}

আপনি কি এটি একটি সংকলন ত্রুটি উত্পন্ন আশা করতে পারেন? এটি এখন খানিকটা পিচ্ছিল হয়ে যায়।
যদি আমরা 3 টি পুনরাবৃত্তি সহ একটি লুপ রাখি এবং লুপটিতে গুণিত করি?

সংকলকটিকে অপ্টিমাইজ করার অনুমতি দেওয়া হয়েছে তবে প্রোগ্রামটি করার সময় এটি আচরণের পরিবর্তন করতে পারে না।


এই কেসটি আসলে কীভাবে পরিচালিত হয় সে সম্পর্কে কিছু তথ্য:

জাভা এবং অন্যান্য অনেক ভাষায়, পূর্ণসংখ্যার মধ্যে একটি নির্দিষ্ট সংখ্যক বিট থাকে। প্রদত্ত সংখ্যা বিটগুলিতে ফিট না করা গণনাগুলি উপচে পড়বে ; গণনাটি মূলত জাভাতে মডুলাস 2 ^ 32 সম্পাদিত হয় যার পরে মানটি একটি স্বাক্ষরিত পূর্ণসংখ্যায় রূপান্তরিত হয়।

অন্যান্য ভাষা বা এপিআই-এর বিটগুলির একটি গতিশীল সংখ্যার ব্যবহার ( BigIntegerজাভাতে), একটি ব্যতিক্রম বাড়িয়ে তোলে বা যাদু মানকে যেমন একটি নম্বর নয় এমন মান সেট করে।


8
আমার জন্য, আপনার বক্তব্য, "সত্য কখনও 2147483648নয় (যদিও 2147483648Lএটি)" সত্যই সেই বিন্দুটিকে সীমাবদ্ধ করেছে যা @र्षাজিই চেষ্টা করার চেষ্টা করছিল।
kdbanman

আহ, দুঃখিত, হ্যাঁ, আমিই ছিলাম। আপনার উত্তরে আমি ধারণা ওভারফ্লো / মডুলার পাটিগণিত অনুপস্থিত। মনে রাখবেন যে আপনি আমার সম্পাদনার সাথে একমত না হলে আপনি আবার রোল করতে পারেন।
মার্টেন বোদেউয়েস

@ ওলস্টেড আপনার সম্পাদনাটি সত্যই সঠিক। এটি অন্তর্ভুক্ত না করার জন্য আমার কারণটি ছিল: যেভাবেই 1024 * 1024 * 1024 * 1024পরিচালনা করা হয় তা নির্বিশেষে আমি জোর দিয়ে বলতে চাইছিলাম যে এটি লেখার মতো নয় 2147473648। এমন অনেকগুলি উপায় রয়েছে (এবং আপনি কয়েকটি তালিকাভুক্ত করেছেন) যে কোনও ভাষা এটির সাথে সম্ভাব্য মোকাবেলা করতে পারে। এটি যুক্তিসঙ্গতভাবে পৃথক এবং দরকারী। সুতরাং আমি এটি ছেড়ে দেব। যখন আপনার কাছে একটি জনপ্রিয় প্রশ্নের উচ্চমানের উত্তর থাকে তখন প্রচুর তথ্য ক্রমবর্ধমানভাবে প্রয়োজনীয় হয়ে ওঠে।
ক্রুঙ্কার

16

দ্বিতীয় রূপটি কেন ত্রুটি তৈরি করে তা আমার কোনও ধারণা নেই।

আচরণ আপনার প্রস্তাবিত - যে, ডায়গনিস্টিক বার্তা উৎপাদনের একটি গণনার বৃহত্তম মান যে একটি পূর্ণসংখ্যা সংরক্ষণ করা যাবে বেশি একটি মান উৎপন্ন - একটি হল বৈশিষ্ট্য । আপনার কোনও বৈশিষ্ট্য ব্যবহার করার জন্য, বৈশিষ্ট্যটি অবশ্যই একটি ভাল ধারণা হিসাবে বিবেচিত, ডিজাইন, নির্দিষ্ট, প্রয়োগ, পরীক্ষিত, নথিভুক্ত এবং ব্যবহারকারীদের কাছে প্রেরণ করা উচিত।

জাভার জন্য, সেই তালিকার এক বা একাধিক জিনিস ঘটেনি, এবং তাই আপনার কাছে বৈশিষ্ট্যটি নেই। আমি জানি না কোনটি; আপনি একটি জাভা ডিজাইনার জিজ্ঞাসা করতে হবে।

সি # এর জন্য, এই সমস্ত কিছুই ঘটেছিল - এখন প্রায় চৌদ্দ বছর আগে - এবং তাই সি # তে সম্পর্কিত প্রোগ্রামটি সি # 1.0 থেকে ত্রুটি তৈরি করেছে produced


45
এটি সহায়ক কিছু যোগ করে না। যদিও জাভাতে ছুরিকাঘাত করা আমার আপত্তি নেই, তবে এটি ওপিএস প্রশ্নের কোনও উত্তর দেয় না।
সেয়েরিয়া

29
@ সিয়েরিয়া: মূল পোস্টারটি "কেন নয়?" জিজ্ঞাসা করছে প্রশ্ন - "পৃথিবী যেভাবে আমার মনে হয় এটি হওয়া উচিত নয় কেন?" প্রকৃত কোড সম্পর্কে একটি সুনির্দিষ্ট প্রযুক্তিগত প্রশ্ন নয় এবং এটি স্ট্যাকওভারফ্লোয়ের জন্য একটি খারাপ প্রশ্ন। একটি অস্পষ্ট এবং ননটেকনিক্যাল প্রশ্নের সঠিক উত্তরটি অস্পষ্ট এবং ননটেকনিকাল হ'ল উদ্বেগজনক হওয়া উচিত। আমি মূল পোস্টারকে আরও ভাল প্রশ্ন জিজ্ঞাসা করতে উত্সাহিত করি এবং "কেন নয়" এড়াতে পারি? প্রশ্ন।
এরিক লিপার্ট

18
@ সিয়েরিয়া: আমি যে নোট গ্রহণ করেছি তার উত্তরও এই অস্পষ্ট এবং প্রযুক্তিগত প্রশ্নের উত্তর দেয় না; প্রশ্নটি হচ্ছে "এটি ত্রুটি কেন নয়?" এবং গৃহীত উত্তরটি "কারণ এটি আইনী"। এটি কেবল প্রশ্নটি বিশ্রাম নিচ্ছে ; "আকাশ সবুজ নয় কেন?" "কারণ এটি নীল" দিয়ে প্রশ্নের উত্তর দেয় না। তবে প্রশ্নটি যেহেতু খারাপ প্রশ্ন তাই আমি উত্তরদাতাকে মোটেই দোষ দিচ্ছি না; উত্তরটি হ'ল দুর্বল প্রশ্নের সঠিক যুক্তিযুক্ত উত্তর।
এরিক লিপার্ট

13
মিঃ এরিক, আমি এই প্রশ্নটি পোস্ট করেছিলাম: "কেন i = 1024 * 1024 * 1024 * 1024; গ্রহে কোনও ত্রুটি রিপোর্ট ছাড়াই?"। আর আরশাজির উত্তর হ'ল আমি কী (সম্ভবত আরও বেশি)। কখনও কখনও আমি খুব নির্ভুলভাবে কোনও প্রশ্ন প্রকাশ করতে পারি না। আমি মনে করি সে কারণেই কিছু লোক স্ট্যাকওভারফ্লোতে কিছু পোস্ট করা প্রশ্নকে আরও সঠিকভাবে সংশোধন করে। আমি মনে করি যদি আমি "কারণ এটি আইনী" উত্তরটি পেতে চাই তবে আমি এই প্রশ্নটি পোস্ট করব না। আমি কয়েকটি "নিয়মিত প্রশ্ন" পোস্ট করার জন্য যথাসাধ্য চেষ্টা করব, তবে দয়া করে আমার মতো এমন একজনকে বুঝতে পারেন যিনি একজন ছাত্র এবং এত পেশাদার না। ধন্যবাদ।
ডাব্লুইউজে

5
@WUJ এই উত্তরটি IMHO অতিরিক্ত অন্তর্দৃষ্টি এবং দৃষ্টিকোণ সরবরাহ করে perspective সমস্ত উত্তর পড়ার পরে আমি এই উত্তরটি অন্য উত্তরগুলির সরবরাহের মতো যথাযথতা দেওয়ার জন্য পেয়েছি। এছাড়াও এটি সচেতনতা বৃদ্ধি করে যে বিকাশকারীরা কিছু সফ্টওয়্যার পণ্যের একমাত্র প্রয়োগকারী নয়।
সফটওয়্যার

12

আরশাজির উত্তর ছাড়াও আমি আরও একটি জিনিস দেখাতে চাই:

এটি অ্যাসাইনমেন্ট নয় যা ত্রুটির কারণ হয়ে থাকে তবে কেবল আক্ষরিক ব্যবহার হয় । আপনি যখন চেষ্টা

long i = 2147483648;

আপনি খেয়াল করতে পারেন এটি intডাবল হাতটি এখনও একটি লেলিটেরাল এবং সীমার বাইরে থাকার কারণে এটি একটি সংকলন-ত্রুটির কারণ ঘটায় ।

সুতরাং- intমূল্যগুলি (এবং সেগুলি সহ অ্যাসাইনমেন্টগুলি সহ) অপারেশনগুলি একটি সংকলন-ত্রুটি ছাড়াই উপচে পড়তে পারে (এবং পাশাপাশি রানটাইম-ত্রুটি ছাড়াই) তবে সংকলকটি কেবলমাত্র তাদের খুব বড়-বড় অক্ষরকে পরিচালনা করতে পারে না।


1
ঠিক। কোনও দীর্ঘকে একটি আন্তঃ নিয়োগের ক্ষেত্রে অন্তর্নিহিত castালাই অন্তর্ভুক্ত। তবে
কাস্ট

4

উত্তর: কারণ এটি ত্রুটি নয়।

পটভূমি: গুণটি 1024 * 1024 * 1024 * 1024একটি ওভারফ্লোতে পরিচালিত করবে। একটি ওভারফ্লো খুব প্রায়ই একটি বাগ হয়। অতিরিক্ত প্রবাহ দেখা দিলে বিভিন্ন প্রোগ্রামিং ভাষা বিভিন্ন আচরণ তৈরি করে different উদাহরণস্বরূপ, সি এবং সি ++ এটিকে স্বাক্ষরিত পূর্ণসংখ্যার জন্য "অপরিজ্ঞাত আচরণ" বলুন, এবং আচরণটি স্বাক্ষরবিহীন পূর্ণসংখ্যাগুলি সংজ্ঞায়িত করা হয়েছে (গাণিতিক ফলাফল গ্রহণ করুন, ফলাফলটি UINT_MAX + 1যতক্ষণ না নেতিবাচক থাকে ততক্ষণ যোগ করুন যতক্ষণ UINT_MAX + 1ফলাফলের চেয়ে বেশি হবে বিয়োগফল UINT_MAX)।

জাভার ক্ষেত্রে, যদি intমানগুলির সাথে অপারেশনের ফলাফল অনুমোদিত ব্যাপ্তিতে না হয়, ধারণাগতভাবে জাভা 2 ^ 32 যুক্ত করে বা বিয়োগ করে যতক্ষণ না ফলাফল অনুমোদিত সীমার মধ্যে থাকে। সুতরাং বিবৃতিটি সম্পূর্ণ আইনী এবং ভুলভ্রান্তিতে নয়। এটি কেবল আপনার ফলাফল আশা করে না এমন ফল দেয় না।

আপনি অবশ্যই যুক্তি দিতে পারেন যে এই আচরণটি সহায়ক কিনা এবং সংকলকটি আপনাকে কোনও সতর্কতা দেয় কিনা। আমি ব্যক্তিগতভাবে বলতে পারি যে একটি সতর্কতা খুব কার্যকর হবে তবে এটি একটি আইনী জাভা হওয়ায় একটি ত্রুটি ভুল হবে।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.