ভাসা এবং ডাবল মধ্যে পার্থক্য কি?


420

আমি ডাবল নির্ভুলতা এবং একক নির্ভুলতার মধ্যে পার্থক্য সম্পর্কে পড়েছি। তবে বেশিরভাগ ক্ষেত্রে, floatএবং doubleবিনিময়যোগ্য বলে মনে হয়, অর্থাত একটি বা অন্যটি ব্যবহার করা ফলাফলকে প্রভাবিত করে না বলে মনে হয়। আসলেই কি এই ঘটনা? কখন ভাসমান এবং ডাবলগুলি বিনিময়যোগ্য হয়? তাদের মধ্যে পার্থক্য কি কি?

উত্তর:


521

বিশাল পার্থক্য.

নামটি থেকে বোঝা যায়, doubleএকটিতে [1] এর যথার্থতা 2x রয়েছে । সাধারণভাবে 15 এর দশমিক অঙ্কের নির্ভুলতা রয়েছে, যখন 7 রয়েছে।floatdoublefloat

এখানে সংখ্যার সংখ্যা কীভাবে গণনা করা হয় তা এখানে:

double52 ম্যান্টিসা বিট + 1 লুকানো বিট রয়েছে: লগ (2 53 ) ÷ লগ (10) = 15.95 সংখ্যা

float23 ম্যান্টিসা বিট রয়েছে + 1 লুকানো বিট: লগ (2 24 ) ÷ লগ (10) = 7.22 সংখ্যা

এই যথাযথ ক্ষতিটি যখন বার বার গণনা করা হয় তখন বৃহত্তর কাটা ত্রুটি জমা হতে পারে

float a = 1.f / 81;
float b = 0;
for (int i = 0; i < 729; ++ i)
    b += a;
printf("%.7g\n", b); // prints 9.000023

যখন

double a = 1.0 / 81;
double b = 0;
for (int i = 0; i < 729; ++ i)
    b += a;
printf("%.15g\n", b); // prints 8.99999999999996

এছাড়াও, ভাসনের সর্বাধিক মান প্রায় 3e38, তবে দ্বিগুণ প্রায় 1.7e308, তাই ব্যবহার করে float"অনন্ত" (যেমন একটি বিশেষ ভাসমান-বিন্দু সংখ্যা) হিট করতে পারে সাধারণ কোনও কিছুর চেয়ে খুব সহজে double, যেমন 60০ এর ফ্যাকটোরিয়াল গণনা করা।

পরীক্ষার সময়, সম্ভবত কয়েকটি পরীক্ষার ক্ষেত্রে এই বিশাল সংখ্যা রয়েছে, যার ফলে আপনি যদি ফ্লোটগুলি ব্যবহার করেন তবে আপনার প্রোগ্রামগুলি ব্যর্থ হতে পারে।


অবশ্যই, কখনও কখনও, এমনকি doubleযথেষ্ট সঠিক হয় না, তাই আমাদের মাঝে মাঝে long double[1] থাকে (উপরের উদাহরণটি ম্যাকের উপরে 9.00000000000000006666 দেয়) তবে সমস্ত ভাসমান পয়েন্ট ধরণের ক্ষেত্রে গোল-বন্ধ ত্রুটিতে ভুগছে , সুতরাং যদি নির্ভুলতা খুব গুরুত্বপূর্ণ হয় (যেমন অর্থ প্রক্রিয়াজাতকরণ) আপনার ব্যবহার করা উচিত intবা একটি ভগ্নাংশ বর্গ।


+=ত্রুটিগুলি দ্রুত জমে যাওয়ায় প্রচুর ভাসমান পয়েন্ট সংখ্যা যোগ করতে ব্যবহার করবেন না । আপনি যদি পাইথন ব্যবহার করেন তবে ব্যবহার করুন fsum। অন্যথায়, কাহান সংক্ষেপণ অ্যালগরিদম বাস্তবায়নের চেষ্টা করুন ।


[1]: দ্য সি এবং সি ++ মান প্রতিনিধিত্ব নির্দিষ্ট না float, doubleএবং long double। এটি সম্ভব যে তিনটিইই আইইইই ডাবল-স্পষ্টতা হিসাবে প্রয়োগ করা হয়েছে। তবুও, বেশিরভাগ আর্কিটেকচারের জন্য (জিসিসি, এমএসভিসি; x86, x64, এআরএম)float হয় প্রকৃতপক্ষে একটি আইইইই একক স্পষ্টতা ফ্লোটিং পয়েন্ট নম্বর (binary32), এবং double হয় একটি আইইইই ডাবল স্পষ্টতা ফ্লোটিং পয়েন্ট নম্বর (binary64)।


9
সংমিশ্রণের জন্য সাধারণ পরামর্শটি হ'ল সংখ্যার আগে আপনার ভাসমান পয়েন্ট সংখ্যাগুলি সংখ্যার (ছোটতম প্রথম) অনুসারে বাছাইয়ের আগে।
আর .. গীটহাব বন্ধ করুন ICE

মনে রাখবেন যে সি / সি ++ ফ্ল্যাট এবং ডাবল প্রায় সর্বদা আইইইই সিঙ্গল এবং ডাবল যথার্থ যথাক্রমে সি / সি ++ দীর্ঘ ডাবল আপনার সিপিইউ, সংকলক এবং ওএসের উপর নির্ভর করে আরও বেশি পরিবর্তনশীল। কখনও কখনও এটি দ্বিগুণ হিসাবে একই, কখনও কখনও এটি কিছু সিস্টেম-নির্দিষ্ট বর্ধিত ফর্ম্যাট, কখনও কখনও এটি আইইইই কোয়াড নির্ভুলতা।
প্লাগওয়াশ

@ আর..গিটহাবস্টোফেল্পিংস: কেন? আপনি ব্যাখ্যা করতে পারেন?
ইনকিউসিটিভ

@ ইনকুসিটিভ: উদাহরণ হিসাবে উদাহরণস্বরূপ 2 ^ 24 টির পরে 2 ^ 24 মানটির পুনরাবৃত্তির সমন্বয়ে একটি অ্যারে বিবেচনা করুন 1. ক্রম সংমিশ্রণ 2 ^ 24 উত্পাদন করে। বিপরীতে 2 ^ 25 উত্পাদন করে। অবশ্যই আপনি উদাহরণগুলি তৈরি করতে পারেন (উদাহরণস্বরূপ এটি 1 এর 2 ^ 25 পুনরাবৃত্তিগুলি তৈরি করুন) যেখানে কোনও অর্ডার একক সঞ্চালকের সাথে বিপর্যয়করভাবে শেষ হয়ে যায় তবে এর মধ্যে ক্ষুদ্রতম-মাত্রা-প্রথমটি সেরা। আরও ভাল করতে আপনার একরকম গাছের দরকার।
আর .. গিথহাব বন্ধ হেল্পিং আইসিসি

56

এখানে স্ট্যান্ডার্ড সি 99 (আইএসও-আইইসি 9899 6.2.5 §10) বা সি ++ 2003 (আইএসও-আইইসি 14882-2003 3.1.9 §8) স্ট্যান্ডার্ড কী বলে:

তিনটি ফ্লোটিং পয়েন্ট ধরনের হয়: float, double, এবং long double। প্রকারটি doubleকমপক্ষে যতটা নির্ভুলতা সরবরাহ করে floatএবং প্রকারটি long doubleকমপক্ষে যতটা নির্ভুলতা সরবরাহ করে double। প্রকারের মানগুলির সেটটি floatহ'ল ধরণের মানগুলির সেটের একটি উপসেট double; প্রকারের মানগুলির সেটটি doubleহ'ল ধরণের মানগুলির সেটের একটি উপসেট long double

সি ++ স্ট্যান্ডার্ড যোগ করেছে:

ভাসমান-পয়েন্ট ধরণের মান উপস্থাপনা বাস্তবায়ন-সংজ্ঞায়িত।

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


27

চতুর্ভুজ সমীকরণ দেওয়া হয়েছে: x 2  - 4.0000000  x  + 3.9999999 = 0, 10 টি উল্লেখযোগ্য অঙ্কের সঠিক শিকড়  হ'ল , r 1 = 2.000316228 এবং r 2  = 1.999683772।

ব্যবহার করে floatএবং double, আমরা একটি পরীক্ষা প্রোগ্রাম লিখতে পারি:

#include <stdio.h>
#include <math.h>

void dbl_solve(double a, double b, double c)
{
    double d = b*b - 4.0*a*c;
    double sd = sqrt(d);
    double r1 = (-b + sd) / (2.0*a);
    double r2 = (-b - sd) / (2.0*a);
    printf("%.5f\t%.5f\n", r1, r2);
}

void flt_solve(float a, float b, float c)
{
    float d = b*b - 4.0f*a*c;
    float sd = sqrtf(d);
    float r1 = (-b + sd) / (2.0f*a);
    float r2 = (-b - sd) / (2.0f*a);
    printf("%.5f\t%.5f\n", r1, r2);
}   

int main(void)
{
    float fa = 1.0f;
    float fb = -4.0000000f;
    float fc = 3.9999999f;
    double da = 1.0;
    double db = -4.0000000;
    double dc = 3.9999999;
    flt_solve(fa, fb, fc);
    dbl_solve(da, db, dc);
    return 0;
}  

প্রোগ্রাম চালানো আমাকে দেয়:

2.00000 2.00000
2.00032 1.99968

নোট করুন যে সংখ্যাগুলি বড় নয় তবে তবুও আপনি ব্যবহার বাতিলকরণের প্রভাব পান float

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


19
  • একটি ডাবল 64 এবং একক নির্ভুলতা (ভাসা) 32 বিট হয়।
  • ডাবলের একটি বড় ম্যান্টিসা (আসল সংখ্যার পূর্ণসংখ্যক বিট) থাকে।
  • যে কোনও ত্রুটি দ্বিগুণ হয়ে যাবে।

12

ফ্লোট-পয়েন্ট গণনার সাথে জড়িত সংখ্যার আকার সর্বাধিক প্রাসঙ্গিক জিনিস নয়। এটি যে গণনা সম্পাদন করা হচ্ছে এটি প্রাসঙ্গিক।

সংক্ষেপে, যদি আপনি কোনও গণনা সম্পাদন করে থাকেন এবং ফলাফলটি অযৌক্তিক সংখ্যা বা পুনরাবৃত্ত দশমিক হয়, তবে সেই সংখ্যাটি আপনি ব্যবহার করছেন সীমাবদ্ধ আকারের ডেটা কাঠামোয় স্কোয়াশ করা হলে গোলাকার ত্রুটি হবে। যেহেতু ডাবল ফ্লোটের দ্বিগুণ আকারের তাই গোলাকার ত্রুটিটি অনেক ছোট হবে।

পরীক্ষাগুলি বিশেষত এমন নম্বর ব্যবহার করতে পারে যা এই ধরণের ত্রুটির কারণ হতে পারে এবং তাই পরীক্ষিত হয়েছিল যে আপনি আপনার কোডটিতে উপযুক্ত টাইপটি ব্যবহার করেছেন।


9

টাইপ ফ্লোট, 32 বিট দীর্ঘ, 7 অঙ্কের যথার্থতা রয়েছে। যদিও এটি খুব বড় বা খুব ছোট পরিসীমা (+/- 3.4 * 10 ^ 38 বা * 10 ^ -38) সহ মানগুলি সঞ্চয় করতে পারে তবে এর মাত্র 7 টি উল্লেখযোগ্য সংখ্যা রয়েছে।

টাইপ ডাবল, 64৪ বিট দীর্ঘ, এর বৃহত্তর পরিসীমা রয়েছে (* 10 ^ + / - 308) এবং 15 অঙ্কের নির্ভুলতা।

টাইপ লম্বা ডাবল নামমাত্র 80 বিট, যদিও একটি প্রদত্ত সংকলক / ওএস জোড় এটিকে সারিবদ্ধকরণের জন্য 12-16 বাইট হিসাবে সংরক্ষণ করতে পারে। লম্বা ডাবলের একটি ক্ষয়ক্ষতি রয়েছে যা কেবল হাস্যকরভাবে বিশাল এবং 19 অঙ্কের যথাযথতা থাকা উচিত। মাইক্রোসফ্ট, তাদের অসীম প্রজ্ঞায়, দীর্ঘ ডাবলকে 8 বাইটের মধ্যে সীমাবদ্ধ করে, এটি সাধারণ ডাবল সমান।

সাধারণভাবে বলতে গেলে, যখন আপনার ফ্লোটিং পয়েন্টের মান / ভেরিয়েবলের প্রয়োজন হয় তখন কেবল দ্বিগুণ টাইপ ব্যবহার করুন। এক্সপ্রেশনগুলিতে ব্যবহৃত লিটারাল ফ্লোটিং পয়েন্ট মানগুলি ডিফল্ট হিসাবে ডাবল হিসাবে গণ্য হবে এবং ভাসমান পয়েন্টের মানগুলি ফেরত পাঠানো বেশিরভাগ গণিত ফাংশন। আপনি যদি কেবল ডাবল ব্যবহার করেন তবে আপনি নিজেকে অনেক মাথাব্যথা এবং টাইপকাস্টিংগুলি সংরক্ষণ করতে পারবেন।



9

আমি কেবল একটি ত্রুটির মধ্যে দৌড়েছি যা আমাকে চিরকালের জন্য বের করে নিয়েছিল এবং সম্ভবত আপনাকে ভাসমান নির্ভুলতার একটি ভাল উদাহরণ দিতে পারে।

#include <iostream>
#include <iomanip>

int main(){
  for(float t=0;t<1;t+=0.01){
     std::cout << std::fixed << std::setprecision(6) << t << std::endl;
  }
}

আউটপুট হয়

0.000000
0.010000
0.020000
0.030000
0.040000
0.050000
0.060000
0.070000
0.080000
0.090000
0.100000
0.110000
0.120000
0.130000
0.140000
0.150000
0.160000
0.170000
0.180000
0.190000
0.200000
0.210000
0.220000
0.230000
0.240000
0.250000
0.260000
0.270000
0.280000
0.290000
0.300000
0.310000
0.320000
0.330000
0.340000
0.350000
0.360000
0.370000
0.380000
0.390000
0.400000
0.410000
0.420000
0.430000
0.440000
0.450000
0.460000
0.470000
0.480000
0.490000
0.500000
0.510000
0.520000
0.530000
0.540000
0.550000
0.560000
0.570000
0.580000
0.590000
0.600000
0.610000
0.620000
0.630000
0.640000
0.650000
0.660000
0.670000
0.680000
0.690000
0.700000
0.710000
0.720000
0.730000
0.740000
0.750000
0.760000
0.770000
0.780000
0.790000
0.800000
0.810000
0.820000
0.830000
0.839999
0.849999
0.859999
0.869999
0.879999
0.889999
0.899999
0.909999
0.919999
0.929999
0.939999
0.949999
0.959999
0.969999
0.979999
0.989999
0.999999

আপনি যেমন 0.83 এর পরে দেখতে পাচ্ছেন, নির্ভুলতা উল্লেখযোগ্যভাবে চলেছে।

তবে, আমি যদি tদ্বিগুণ হিসাবে সেট আপ করি তবে এ জাতীয় সমস্যাটি ঘটবে না।

এই ক্ষুদ্র ত্রুটিটি বুঝতে আমার পাঁচ ঘন্টা সময় লেগেছে, যা আমার প্রোগ্রামটি নষ্ট করে দিয়েছে।


4
কেবলমাত্র নিশ্চিত হওয়ার জন্য: আপনার সমস্যার সমাধানটি কোনও পছন্দ ব্যবহার করা উচিত? আপনি যদি 100 বার পুনরাবৃত্তি করতে চান তবে আপনার ডাবল ব্যবহার না করে একটি
ইন্টির

8
এখানে ব্যবহার doubleকরা ভাল সমাধান নয়। intআপনার ভাসমান-পয়েন্টের মান পাওয়ার জন্য আপনি অভ্যন্তরীণ গুণকে গণনা এবং করতে ব্যবহার করেন।
রিচার্ড

8

ডাবলসের চেয়ে ফ্লোটে কম নির্ভুলতা রয়েছে। যদিও আপনি ইতিমধ্যে জানেন, আরও ভাল বোঝার জন্য আমাদের ভাসমান-পয়েন্ট পাটিগণিত সম্পর্কে যা জানা উচিত তা পড়ুন।



3

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


3

অন্তর্নির্মিত তুলনা অপারেশনগুলির সাথে পৃথক হয় যখন আপনি ভাসমান পয়েন্টের সাথে 2 সংখ্যার তুলনা করেন, তথ্যের ধরণের পার্থক্য (যেমন ভাসা বা ডাবল) বিভিন্ন ফলাফলের ফলাফল হতে পারে।


1

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


-1

একটি int(পুরো সংখ্যা) থেকে পৃথক, floatএকটি দশমিক পয়েন্ট থাকে এবং তাই করতে পারে a double। তবে উভয়ের মধ্যে পার্থক্যটি হ'ল ক doubleএর দ্বিগুণ বিশদ হিসাবে floatঅর্থাত্ এটি দশমিক বিন্দুর পরে সংখ্যার দ্বিগুণ হতে পারে।


4
এর অর্থ মোটেও নয়। এর অর্থ হ'ল দ্বিগুণ সংখ্যক অখণ্ড দশমিক অঙ্ক এবং এটি দ্বিগুণেরও বেশি। ভগ্নাংশের অঙ্ক এবং নির্ভুলতার মধ্যে সম্পর্ক লিনিয়ার নয়: এটি মানটির উপর নির্ভর করে: উদাহরণস্বরূপ 0.5 যথাযথ তবে 0.33333333333333333333 নয়।
লার্নের মারকুইস
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.