গোল () সঠিকভাবে গোল হয় না বলে মনে হচ্ছে


123

রাউন্ড () ফাংশনের জন্য ডকুমেন্টেশন সূচিত করে যে আপনি এটি একটি সংখ্যা এবং গোলকে দশমিকের পরে অবস্থানগুলি পাস করেন। সুতরাং এটি এটি করা উচিত :

n = 5.59
round(n, 1) # 5.6

তবে, বাস্তবে, ভাল পুরানো ভাসমান পয়েন্ট অদ্ভুততা কৃপণ হয় এবং আপনি পাবেন:

5.5999999999999996

ইউআই এর উদ্দেশ্যে, আমার প্রদর্শন করা দরকার 5.6। আমি ইন্টারনেট ঘুরে দেখলাম এবং কিছু ডকুমেন্টেশন পেয়েছি যে এটি আমার পাইথন প্রয়োগের উপর নির্ভরশীল। দুর্ভাগ্যক্রমে, এটি আমার উইন্ডোজ ডেভ মেশিন এবং প্রতিটি লিনাক্স সার্ভারে চেষ্টা করেছি both এখানেও দেখুন

আমার নিজস্ব বৃত্তাকার লাইব্রেরি তৈরির সংক্ষিপ্ততা, এখানে কি কোনও উপায় আছে?


4
আমি পাইথন 2.7.11 বৃত্তাকার (5.59) এর সাথে এই চেষ্টা এবং এটি উভয় উইন্ডোতে 5.6 এবং Linux এক্স 86 64 বিট মেশিন, Cython (ডকুমেন্টেশন লিংক উল্লেখ এখন পরিবর্তিত হয় আমি) হিসাবে ফলাফলের দিচ্ছেন?
অ্যালেক্স Punnen

2
যেখানে এটি আসলে সঠিকভাবে কাজ করে না তা হ'ল round(5.55, 1) = 5.5
দিমিত্রি

উত্তর:


101

এটি যেভাবে সঞ্চিত হয় তাতে আমি সহায়তা করতে পারি না, তবে কমপক্ষে বিন্যাসটি সঠিকভাবে কাজ করে:

'%.1f' % round(n, 1) # Gives you '5.6'

11
আমি চেষ্টা করেছিলাম print '%.2f' % 655.665কিন্তু এটি ফিরে আসে 655.66, এটি হওয়া উচিত655.67
লিজা

1
@Kyrie দেখতে stackoverflow.com/questions/9301690/... । ভাসমান পয়েন্টের অসতর্কতাটি এখানে দোষ দেওয়া - "5.665 -> 5.67" তবে "15.665 -> 15.66"। দশমিকগুলি ব্যবহার করুন যদি আপনার সঠিক নির্ভুলতার প্রয়োজন হয়।
জিমি

7
এটি অনুসন্ধানের পরে কাজ করছে :) ভাসমান পয়েন্টগুলিতে # ইস্যু এবং সীমাবদ্ধতার from decimal import Decimal, ROUND_HALF_UP, ROUND_HALF_DOWNবৃত্তাকারে # ব্যবহার করুনDecimal(str(655.665)).quantize(Decimal('1.11'), rounding=ROUND_HALF_UP)
লিজা

102

বিন্যাস না করেও ফর্ম্যাটিং সঠিকভাবে কাজ করে:

"%.1f" % n

18
ডক্স অনুসারে , স্ট্রিং ফর্ম্যাটিংয়ের এই স্টাইলটি শেষ পর্যন্ত চলে যাবে। নতুন ধাঁচের ফর্ম্যাটটি হবে"{:.1f}".format(n)
Whereswalden

2
সঠিকভাবে গোল হয় না: '%.5f' % 0.988625দেয়0.98862
স্ক্ল্যামার

@ স্ক্ল্যামার: এটি গোলাকার () এর আচরণের পাশাপাশি: বৃত্তাকার (0.988625,5) এছাড়াও 0.98862 দেয়। গোল (0.988626,5) পাশাপাশি "% .5f"% 0.988626 0.98863 দিন
ভিঙ্কো ভার্সালভিক

দুর্ভাগ্যক্রমে "% .2f"% 2.675 ২.6767 ফিরে আসবে - যা এই পদ্ধতিটি ব্যবহার করে এবং ২.6868 প্রত্যাশা করে তাদের জন্য অপ্রত্যাশিত উত্তর হতে পারে
ডায়ান

30

আপনি যদি দশমিক মডিউলটি ব্যবহার করেন তবে আপনি 'রাউন্ড' ফাংশনটি ব্যবহার না করে আনুমানিক পারেন। বিশেষত আর্থিক অ্যাপ্লিকেশনগুলি লেখার সময় আমি এখানে গোলাকার জন্য যা ব্যবহার করেছি তা এখানে:

Decimal(str(16.2)).quantize(Decimal('.01'), rounding=ROUND_UP)

এটি দশমিক সংখ্যাটি ফেরত দেবে যা 16.20।


4
এটি আধ্যাত্মিক উত্তর - যেখানে নির্ভুলতার বিষয়টি যেখানেই হোক না কেন, যা সর্বত্র বেশ সুন্দর pretty অবশ্যই: এটি কিছুটা ভার্জোজ । তবে সেই স্তন্যপানটিকে কোনও সহায়ক ফাংশনে ফেলে দিন এবং আপনি ফর্ম্যাট করে খুব ভাল।
সিসিল কারি

2
rounding='ROUND_UP'
এলএমসি

এই ত্রুটি পান, তাহলে NameError: global name 'ROUND_UP' is not definedআপনি আপনার rounding ফাংশন আমদানি করা প্রয়োজন: from decimal import Decimal, ROUND_UPঅন্যান্য রাউন্ডিং ফাংশন
স্টিফেন ব্লেয়ার

আপনার উদাহরণটি এখনও বিপজ্জনক বলে মনে হচ্ছে: আপনি str () দ্বারা প্রদত্ত রাউন্ডিংয়ের উপর নির্ভর করেন।
YvesgereY

21

round(5.59, 1)ভাল কাজ করছে। সমস্যাটি হ'ল 5.6 ঠিক বাইনারি ভাসমান পয়েন্টে উপস্থাপন করা যায় না।

>>> 5.6
5.5999999999999996
>>> 

ভিঙ্কো যেমন বলেছেন, আপনি প্রদর্শনের জন্য রাউন্ডিং করতে স্ট্রিং ফর্ম্যাটিং ব্যবহার করতে পারেন।

পাইথনের দশমিক গাণিতিকের জন্য একটি মডিউল রয়েছে যদি আপনার এটির প্রয়োজন হয়।


1
পাইথন ২.7 বা পাইথন ৩.৫
vy32


10

আপনি কোনও পূর্ণসংখ্যায় ডেটা টাইপ পরিবর্তন করতে পারেন:

>>> n = 5.59
>>> int(n * 10) / 10.0
5.5
>>> int(n * 10 + 0.5)
56

এবং তারপরে লোকেলের দশমিক বিভাজক সন্নিবেশ করে নম্বরটি প্রদর্শন করুন।

তবে জিমির উত্তর আরও ভাল।


5

ভাসমান পয়েন্টের গণিতটি সামান্য, তবে বিরক্তিকর, নির্ভুলতা ভুল to আপনি যদি পূর্ণসংখ্যা বা স্থির বিন্দু নিয়ে কাজ করতে পারেন তবে আপনাকে নিশ্চয়তার গ্যারান্টি দেওয়া হবে।


5

কটাক্ষপাত ডেসিমাল মডিউল

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

এবং

দশমিক সংখ্যা হুবহু উপস্থাপন করা যেতে পারে। বিপরীতে, 1.1 এবং 2.2 এর মতো সংখ্যার বাইনারি ভাসমান বিন্দুতে যথাযথ উপস্থাপনা নেই। শেষ ব্যবহারকারীরা সাধারণত 1.1 + 2.2 বাইনারি ভাসমান পয়েন্ট হিসাবে এটি 3.300000000000000003 হিসাবে প্রদর্শিত হবে আশা করবে না।

ডেসিমাল অপারেশন এটি যে ফ্লোটিং পয়েন্ট অপারেশন প্রয়োজন হয় এবং লেখার অ্যাপ্লিকেশানে সহজ করতে ধরনের উপলব্ধ এছাড়াও একটি মানবিক পাঠযোগ্য বিন্যাসে সেই ফলাফল উপস্থাপন, যেমন, অ্যাকাউন্টিং করা প্রয়োজন।



4

আসলেই এটি একটি বড় সমস্যা। এই কোড ব্যবহার করে দেখুন:

print "%.2f" % (round((2*4.4+3*5.6+3*4.4)/8,2),)

এটি প্রদর্শিত হয় 4.85। তারপরে আপনি:

print "Media = %.1f" % (round((2*4.4+3*5.6+3*4.4)/8,1),)

এবং এটি দেখায় 4.8। আপনি কি হাতে হাতে গণনা করে সঠিক উত্তরটি 4.85, তবে যদি আপনি চেষ্টা করেন:

print "Media = %.20f" % (round((2*4.4+3*5.6+3*4.4)/8,20),)

আপনি সত্যটি দেখতে পাচ্ছেন: ভাসমান পয়েন্টটি ভগ্নাংশের নিকটতম সসীম যোগ হিসাবে সংরক্ষণ করা হয় যার ডোনামিটার দুটি হিসাবে শক্তি।


3

আপনি %স্প্রিন্টফের মতো স্ট্রিং ফর্ম্যাট অপারেটরটি ব্যবহার করতে পারেন ।

mystring = "%.2f" % 5.5999


2

আমি করিতেছি:

int(round( x , 0))

এই ক্ষেত্রে, আমরা প্রথমে ইউনিট স্তরে যথাযথভাবে বৃত্তাকার করি, তারপরে একটি ফ্লোট মুদ্রণ এড়াতে আমরা পূর্ণসংখ্যায় রূপান্তর করি।

সুতরাং

>>> int(round(5.59,0))
6

আমি মনে করি এই উত্তরটি স্ট্রিং গঠনের চেয়ে আরও ভাল কাজ করে এবং এটি বৃত্তাকার ফাংশনটি ব্যবহার করতে আমার আরও সংবেদনশীল করে তোলে।


2

আমি এক্ষেত্রে একেবারেই নির্ভর করা এড়াতে চাই round()। বিবেচনা

print(round(61.295, 2))
print(round(1.295, 2))

আউটপুট হবে

61.3
1.29

যদি আপনার নিকটতম পূর্ণসংখ্যার শক্ত বৃত্তাকার প্রয়োজন হয় তবে এটি পছন্দসই আউটপুট নয়। এই আচরণটি বাইপাস করতে যান math.ceil()(বা math.floor()আপনি যদি গোলটি করতে চান):

from math import ceil
decimal_count = 2
print(ceil(61.295 * 10 ** decimal_count) / 10 ** decimal_count)
print(ceil(1.295 * 10 ** decimal_count) / 10 ** decimal_count)

আউটপুট

61.3
1.3

আশা করি এইটি কাজ করবে.


1

কোড:

x1 = 5.63
x2 = 5.65
print(float('%.2f' % round(x1,1)))  # gives you '5.6'
print(float('%.2f' % round(x2,1)))  # gives you '5.7'

আউটপুট:

5.6
5.7

0

এখানে আমি যেখানে ব্যর্থতা দেখছি। আপনি যদি এই 2 সংখ্যাকে এক দশমিক স্থানে নিয়ে যেতে চান? 23.45 23.55 আমার শিক্ষাগুলি ছিল যে এগুলি গোল করা থেকে আপনার প্রাপ্তি হওয়া উচিত: 23.4 23.6 "বিধি" হ'ল আগের সংখ্যাটি বিজোড় হলে আপনার বৃত্তাকার হওয়া উচিত, পূর্ববর্তী সংখ্যাটি সমান হলে গোল না করে। পাইথনের বৃত্তাকার ক্রিয়াটি কেবল 5 টি কেটে দেয়।


1
আপনি যে বিষয়ে কথা বলছেন তা হ'ল "ব্যাঙ্কারদের রাউন্ডিং" , রাউন্ডিং করানোর বিভিন্ন উপায়গুলির মধ্যে একটি।
সাইমন MᶜKenzie

0

সমস্যাটি তখনই হয় যখন শেষ অঙ্কটি 5 হয়। 0.045 অভ্যন্তরীণভাবে 0.044999999999999 হিসাবে সঞ্চিত আছে ... আপনি কেবল শেষের সংখ্যাটি 6 এ বৃদ্ধি করতে পারেন এবং রাউন্ড অফ করতে পারেন। এটি আপনাকে পছন্দসই ফলাফল দেবে।

import re


def custom_round(num, precision=0):
    # Get the type of given number
    type_num = type(num)
    # If the given type is not a valid number type, raise TypeError
    if type_num not in [int, float, Decimal]:
        raise TypeError("type {} doesn't define __round__ method".format(type_num.__name__))
    # If passed number is int, there is no rounding off.
    if type_num == int:
        return num
    # Convert number to string.
    str_num = str(num).lower()
    # We will remove negative context from the number and add it back in the end
    negative_number = False
    if num < 0:
        negative_number = True
        str_num = str_num[1:]
    # If number is in format 1e-12 or 2e+13, we have to convert it to
    # to a string in standard decimal notation.
    if 'e-' in str_num:
        # For 1.23e-7, e_power = 7
        e_power = int(re.findall('e-[0-9]+', str_num)[0][2:])
        # For 1.23e-7, number = 123
        number = ''.join(str_num.split('e-')[0].split('.'))
        zeros = ''
        # Number of zeros = e_power - 1 = 6
        for i in range(e_power - 1):
            zeros = zeros + '0'
        # Scientific notation 1.23e-7 in regular decimal = 0.000000123
        str_num = '0.' + zeros + number
    if 'e+' in str_num:
        # For 1.23e+7, e_power = 7
        e_power = int(re.findall('e\+[0-9]+', str_num)[0][2:])
        # For 1.23e+7, number_characteristic = 1
        # characteristic is number left of decimal point.
        number_characteristic = str_num.split('e+')[0].split('.')[0]
        # For 1.23e+7, number_mantissa = 23
        # mantissa is number right of decimal point.
        number_mantissa = str_num.split('e+')[0].split('.')[1]
        # For 1.23e+7, number = 123
        number = number_characteristic + number_mantissa
        zeros = ''
        # Eg: for this condition = 1.23e+7
        if e_power >= len(number_mantissa):
            # Number of zeros = e_power - mantissa length = 5
            for i in range(e_power - len(number_mantissa)):
                zeros = zeros + '0'
            # Scientific notation 1.23e+7 in regular decimal = 12300000.0
            str_num = number + zeros + '.0'
        # Eg: for this condition = 1.23e+1
        if e_power < len(number_mantissa):
            # In this case, we only need to shift the decimal e_power digits to the right
            # So we just copy the digits from mantissa to characteristic and then remove
            # them from mantissa.
            for i in range(e_power):
                number_characteristic = number_characteristic + number_mantissa[i]
            number_mantissa = number_mantissa[i:]
            # Scientific notation 1.23e+1 in regular decimal = 12.3
            str_num = number_characteristic + '.' + number_mantissa
    # characteristic is number left of decimal point.
    characteristic_part = str_num.split('.')[0]
    # mantissa is number right of decimal point.
    mantissa_part = str_num.split('.')[1]
    # If number is supposed to be rounded to whole number,
    # check first decimal digit. If more than 5, return
    # characteristic + 1 else return characteristic
    if precision == 0:
        if mantissa_part and int(mantissa_part[0]) >= 5:
            return type_num(int(characteristic_part) + 1)
        return type_num(characteristic_part)
    # Get the precision of the given number.
    num_precision = len(mantissa_part)
    # Rounding off is done only if number precision is
    # greater than requested precision
    if num_precision <= precision:
        return num
    # Replace the last '5' with 6 so that rounding off returns desired results
    if str_num[-1] == '5':
        str_num = re.sub('5$', '6', str_num)
    result = round(type_num(str_num), precision)
    # If the number was negative, add negative context back
    if negative_number:
        result = result * -1
    return result

0

আর একটি সম্ভাব্য বিকল্প হ'ল:

def hard_round(number, decimal_places=0):
    """
    Function:
    - Rounds a float value to a specified number of decimal places
    - Fixes issues with floating point binary approximation rounding in python
    Requires:
    - `number`:
        - Type: int|float
        - What: The number to round
    Optional:
    - `decimal_places`:
        - Type: int 
        - What: The number of decimal places to round to
        - Default: 0
    Example:
    ```
    hard_round(5.6,1)
    ```
    """
    return int(number*(10**decimal_places)+0.5)/(10**decimal_places)

-4

কি সম্পর্কে:

round(n,1)+epsilon

এটি কেবল তখনই কাজ করবে যদি এপসিলনের দ্বারা রাউন্ডিংটি নিয়মিতভাবে রাউন্ড নম্বর থেকে দূরে থাকে। তাহলে epsilon = .000001তারপর round(1.0/5.0, 1) + epsilonসুনির্দিষ্ট উপস্থাপনা 0.2 গ্রহণ করা এবং এটা 0,00001 করতে হবে। যদি অ্যাপসিলনটি রাউন্ড ফাংশনের অভ্যন্তরে থাকে তবে একইভাবে খারাপ সমস্যাও ঘটত।
মাইকেল স্কট কুথবার্ট
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.