ম্যাথ.অ্যাবস পূর্ণসংখ্যার জন্য ভুল মান প্রদান করে M


উত্তর:


102

Integer.MIN_VALUEহয় -2147483648, তবে 32 বিট পূর্ণসংখ্যার সমন্বিত সর্বোচ্চ মানটি +2147483647+214748364832 বিট ইনট্রে উপস্থাপনের চেষ্টা কার্যকরভাবে "রোল ওভার" হয়ে যাবে -2147483648। কারণ এটি স্বাক্ষরিত পূর্ণসংখ্যাগুলি ব্যবহার করার সময়, দু'জনের পরিপূরক বাইনারি উপস্থাপনা +2147483648এবং -2147483648অভিন্ন। +2147483648সীমা ছাড়াই বিবেচিত এটি কোনও সমস্যা নয় ।

এই বিষয়ে আরও কিছু পড়ার জন্য, আপনি টু এর পরিপূরক সম্পর্কিত উইকিপিডিয়া নিবন্ধটি পরীক্ষা করে দেখতে চাইতে পারেন ।


6
ঠিক আছে, কোনও সমস্যা প্রভাবটিকে হ্রাস করে না, এটি সমস্যাগুলি খুব ভাল বোঝাতে পারে। ব্যক্তিগতভাবে আমার পরিবর্তে একটি ব্যতিক্রম বা একটি সংখ্যা সিস্টেম থাকবে যা উচ্চ স্তরের ভাষায় গতিশীলভাবে বৃদ্ধি পায়।
মার্টেন বোদেউয়েস

40

আপনি যে আচরণটি নির্দেশ করেছেন তা প্রকৃতপক্ষে, পাল্টা স্বজ্ঞাত। যাইহোক, এই আচরণটি জাভাদোকMath.abs(int) দ্বারা নির্দিষ্ট করাগুলির জন্য :

যুক্তিটি নেতিবাচক না হলে যুক্তিটি ফিরে আসে। যুক্তিটি নেতিবাচক হলে, যুক্তির অবহেলা ফিরে আসে।

এটি হ'ল Math.abs(int)নিম্নলিখিত জাভা কোডের মতো আচরণ করা উচিত:

public static int abs(int x){
    if (x >= 0) {
        return x;
    }
    return -x;
}

যে, নেতিবাচক ক্ষেত্রে -x,।

জেএলএস বিভাগ 15.15.4 অনুসারে , -xসমান (~x)+1, যেখানে ~বিটওয়াইস পরিপূরক অপারেটর।

এটি ঠিক আছে কিনা তা যাচাই করতে, উদাহরণ হিসাবে উদাহরণস্বরূপ -1 নিই।

পূর্ণসংখ্যার মানটি জাভাতে হেক্সাডেসিমাল -1হিসাবে উল্লেখ করা যেতে পারে 0xFFFFFFFF(এটি কোনও printlnবা অন্য কোনও পদ্ধতিতে পরীক্ষা করে দেখুন)। -(-1)এইভাবে গ্রহণ করা দেয়:

-(-1) = (~(0xFFFFFFFF)) + 1 = 0x00000000 + 1 = 0x00000001 = 1

সুতরাং, এটি কাজ করে।

আসুন এখন দিয়ে চেষ্টা করা যাক Integer.MIN_VALUE। সর্বনিম্ন পূর্ণসংখ্যার দ্বারা প্রতিনিধিত্ব করা যেতে পারে তা জেনে 0x80000000, প্রথম বিটটি 1 এ সেট হয় এবং 31 টি বিট 0 সেট করে, আমাদের কাছে:

-(Integer.MIN_VALUE) = (~(0x80000000)) + 1 = 0x7FFFFFFF + 1 
                     = 0x80000000 = Integer.MIN_VALUE

আর এই কেন Math.abs(Integer.MIN_VALUE)আয় Integer.MIN_VALUE। এছাড়াও মনে রাখবেন 0x7FFFFFFFহয় Integer.MAX_VALUE

এটি বলেছিল, ভবিষ্যতে এই প্রতি-স্বজ্ঞাত রিটার্ন মানের কারণে আমরা কীভাবে সমস্যাগুলি এড়াতে পারি?

  • @ বোম্বের নির্দেশ অনুসারে আমরা আমাদের এসটিকে আগে ফেলে intদিতে পারি long। আমাদের অবশ্য হয়

    • এগুলিকে আবার intগুলি করে দিন, যা কাজ করে না Integer.MIN_VALUE == (int) Math.abs((long)Integer.MIN_VALUE)
    • বা longএকরকম আশা করে চালিয়ে যাও যে আমরা কখনই তার Math.abs(long)সমান মান নিয়ে কল করব না Long.MIN_VALUE, যেহেতু আমাদেরও রয়েছে Math.abs(Long.MIN_VALUE) == Long.MIN_VALUE
  • আমরা BigIntegerযে BigInteger.abs()কোনও জায়গায় ব্যবহার করতে পারি , কারণ সত্যই সর্বদা একটি ইতিবাচক মান দেয়। এটি একটি ভাল বিকল্প, যদিও কাঁচা পূর্ণসংখ্যার ধরণের হস্তক্ষেপের তুলনায় কিছুটা ধীর।

  • আমরা এর জন্য আমাদের নিজস্ব র‍্যাপারটি লিখতে পারি Math.abs(int):

/**
 * Fail-fast wrapper for {@link Math#abs(int)}
 * @param x
 * @return the absolute value of x
 * @throws ArithmeticException when a negative value would have been returned by {@link Math#abs(int)}
 */
public static int abs(int x) throws ArithmeticException {
    if (x == Integer.MIN_VALUE) {
        // fail instead of returning Integer.MAX_VALUE
        // to prevent the occurrence of incorrect results in later computations
        throw new ArithmeticException("Math.abs(Integer.MIN_VALUE)");
    }
    return Math.abs(x);
}
  • একটি পূর্ণসংখ্যা, bitwise ব্যবহার করুন এবং উচ্চ বিট পরিষ্কার, নিশ্চিত ফলাফলের অ নেতিবাচক হল: int positive = value & Integer.MAX_VALUE(মূলত থেকে সজল Integer.MAX_VALUEকরার 0পরিবর্তে Integer.MIN_VALUE)

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


12

এখানে কি জাভা দস্তাবেজে অন্তর্ভুক্ত Math.abs () জন্য বলছেন javadoc :

মনে রাখবেন যে আর্গুমেন্টটি যদি পূর্ণসংখ্যার মানের সমান হয় M


4

আপনি যে ফলাফলটি প্রত্যাশা করছেন তা দেখতে, কাস্ট Integer.MIN_VALUEকরুন long:

System.out.println(Math.abs((long) Integer.MIN_VALUE));

4
একটি সম্ভাব্য সংশোধন, সত্যিই! যাইহোক, এটি Math.absনেতিবাচক সংখ্যাটি ফিরিয়ে Math.abs(Long.MIN_VALUE) == Long.MIN_VALUE
পাল্টে

4
@ বার্নার্ডপুলাস, ভাল, একটি নিক্ষেপ করা ছাড়াও এটি করার কী আছে ArithmeticException? এছাড়াও, আচরণটি এপিআই ডকুমেন্টেশনে স্পষ্টতই নথিভুক্ত করা হয়েছে।
বোম্বে

সেখানে আপনার প্রশ্নের কোন ভাল উত্তর ... আমি শুধু থেকে দেখান যে এই আচরণ, যা বাগ একটি উৎস, ব্যবহার দ্বারা সংশোধন করা হয় না চেয়েছিলেন Math.abs(long)। আমি এখানে আমার ভুলের জন্য ক্ষমা চাইছি: আমি চেষ্টা করেছিলাম যে আপনি Math.abs(long)একটি সমাধান হিসাবে ব্যবহারের প্রস্তাব করেছিলেন , যখন আপনি "প্রশ্নকারী প্রত্যাশা করছেন ফলাফলটি দেখার" এটি একটি সহজ উপায় হিসাবে দেখিয়েছেন। দুঃখিত
বার্নার্ড পলুস

জাভা 15 এ নতুন পদ্ধতিগুলি সহ বাস্তবে একটি ব্যতিক্রম ছোঁড়া হয়।
চিপার্তেটিজ

1

2147483648 জাভাতে কোনও পূর্ণসংখ্যার মধ্যে সংরক্ষণ করা যায় না, এর বাইনারি উপস্থাপনা -2147483648 এর সমান।


0

তবে (int) 2147483648L == -2147483648 একটি নেতিবাচক সংখ্যা রয়েছে যার কোনও ধনাত্মক সমতুল্য নেই তাই এর জন্য ধনাত্মক মান নেই। আপনি Long.MAX_VALUE এর সাথে একই আচরণ দেখতে পাবেন।


0

জাভাতে এটির একটি সমাধান রয়েছে 15 এটি ইনট এবং দীর্ঘ পদ্ধতি হবে method তারা ক্লাসে উপস্থিত হবে

java.lang.Math and java.lang.StrictMath

পদ্ধতিগুলি।

public static int absExact(int a)
public static long absExact(long a)

পাস করলে

Integer.MIN_VALUE

বা

Long.MIN_VALUE

একটি ব্যতিক্রম নিক্ষেপ করা হয়।

https://bugs.openjdk.java.net/browse/JDK-8241805

আমি দেখতে চাই যে লম্বা.এম.এ.ভি.এল.এইউ বা পূর্ণসংখ্যা। এম.এক্স.এল.এল.এল.কে পাস করার পরে একটি ইতিবাচক মানটি ফিরে আসবে এবং ব্যতিক্রম নয়।


-1

ম্যাথ.এবসগুলি বড় সংখ্যা সহ সব সময় কাজ করে না আমি এই ছোট কোড যুক্তিটি ব্যবহার করি যা আমি যখন 7 বছর বয়সে শিখেছিলাম!

if(Num < 0){
  Num = -(Num);
} 

sএখানে কি ?
আইয়ুব

দুঃখিত, আমি আমার মূল কোডটি থেকে আপডেট করতে ভুলে গেছি
ডেভ

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