কিভাবে ভাসমান পয়েন্ট নম্বর পূর্ণসংখ্যায় রূপান্তর করবেন?


47

বাশ-তে পূর্ণসংখ্যার রূপান্তর করতে এটি কি ভাসা করার সঠিক উপায়? অন্য কোন পদ্ধতি আছে?

flotToint() {
    printf "%.0f\n" "$@"
}

5
সঠিকটা কি"?
জোসেফ আর।

আমি শুধু নিশ্চিত করতে চাই .. এই অধিকার নাকি এর চেয়ে ভাল আছে?
রাহুল পাতিল

2
%.0fউপরে বা নীচে বৃত্তাকার হবে। তুমি কি এটাই চাও? আপনি printf "%d\n" "$@" 2>/dev/nullভগ্নাংশটি কাটাতে ব্যবহার করতে পারেন ।
অট--

উত্তর:


69

সজোরে আঘাত

ইন bash, এটি সম্ভবত এটি হিসাবে হিসাবে ভাল। এটি একটি শেল বিল্টিন ব্যবহার করে। যদি আপনার কোনও ভেরিয়েবলের ফলাফলের প্রয়োজন হয় তবে আপনি কমান্ড সাবস্টিটিউশন বা bashনির্দিষ্টটি ব্যবহার করতে পারেন (যদিও এখন এটি দ্বারা সমর্থিত zsh):

printf -v int %.0f "$float"

আপনি করতে পারেন:

float=1.23
int=${float%.*}

তবে এটি আপনাকে নিকটতম পূর্ণসংখ্যার পরিবর্তে ভগ্নাংশটি সরিয়ে ফেলবে এবং এটি $floatপছন্দ 1.2e9বা .12উদাহরণের মানগুলির জন্য কাজ করবে না ।

ভাসমানগুলির অভ্যন্তরীণ উপস্থাপনের কারণে সম্ভাব্য সীমাবদ্ধতাগুলিও নোট করুন:

$ printf '%.0f\n' 1e50
100000000000000007629769841091887003294964970946560

আপনি একটি পূর্ণসংখ্যার পেতে পারেন, তবে সম্ভাবনা হ'ল আপনি এই সংখ্যার কোথাও ব্যবহার করতে পারবেন না।

এছাড়াও, যেমন @BinaryZebra দ্বারা লক্ষনীয়, বিভিন্ন মধ্যে printfবাস্তবায়ন (ব্যাশ, ksh93, যশ, না গনুহ, zsh, ড্যাশ), এটা লোকেল (দশমিক বিভাজক যা হতে পারে দ্বারা প্রভাবিত হয় .অথবা ,)।

সুতরাং, যদি আপনার ভাসমানগুলি সর্বদা দশমিক বিভাজক হিসাবে প্রকাশ করা হয় এবং আপনি যদি চান যে এটির printfস্ক্রিপ্টটি ব্যবহারকারীর লোকাল নির্বিশেষে আপনি এটির মতো চিকিত্সা করেন তবে আপনাকে লোকেলটি সিতে ঠিক করতে হবে:

LC_ALL=C printf '%.0f' "$float"

সহ yash, আপনি এটি করতে পারেন:

printf '%.0f' "$(($float))"

(নিচে দেখ).

POSIX

printf "%.0f\n" 1.1

পসিক্স %fসমর্থন করে না যেমন পসিক্স নয়।

প্যাসিকলি, আপনি এটি করতে পারেন:

f2i() {
  awk 'BEGIN{for (i=1; i<ARGC;i++)
   printf "%.0f\n", ARGV[i]}' "$@"
}

এটির লোকাল দ্বারা প্রভাবিত হয় না (কমাটি দশমিক বিভাজক হতে পারে না awkকারণ এটি ইতিমধ্যে সিনট্যাক্সের একটি বিশেষ চরিত্র ( print 1,2যেমন print 1, 2দুটি আর্গুমেন্ট পাস করার মতো print)

zsh

ইন zsh(যা ফ্লোটিং পয়েন্ট গাণিতিক সমর্থন (দশমিক বিভাজক সবসময় সময়ের) হল), আপনি rint()আপনার সবচেয়ে কাছের পূর্ণসংখ্যা একটি float হিসাবে (মত দিতে গণিত ফাংশন C) এবং int()একটি float (মত থেকে একটি পূর্ণসংখ্যা দিতে awk)। সুতরাং আপনি এটি করতে পারেন:

$ zmodload zsh/mathfunc
$ i=$((int(rint(1.234e2))))
$ echo $i
123

বা:

$ integer i=$((rint(5.678e2)))
$ echo $i
568

তবে মনে রাখবেন যে doubleএসগুলি খুব বেশি সংখ্যক প্রতিনিধিত্ব করতে পারে, পূর্ণসংখ্যাগুলি অনেক বেশি সীমাবদ্ধ।

$ printf '%.0f\n' 1e123
999999999999999977709969731404129670057984297594921577392083322662491290889839886077866558841507631684757522070951350501376
$ echo $((int(1e123)))
-9223372036854775808

ksh93

ksh93 হ'ল প্রথম বোর্নের মতো শেল যা ভাসমান পয়েন্ট গণিতকে সমর্থন করে। ksh93 কমান্ড কেবল অন্তর্নির্মিত কমান্ড যখন পাইপ ব্যবহার না করে বা কাঁটাচামচ ব্যবহার না করে কমান্ড প্রতিস্থাপনকে অনুকূল করে তোলে। সুতরাং

i=$(printf '%.0f' "$f")

কাঁটাচামচ করে না বা আরও ভাল:

i=${ printf '%.0f' "$f"; }

যা উভয়ই কাঁটাচামচ করে না তবে নকল সাব্হেল পরিবেশ তৈরি করার সমস্ত ঝামেলাও করে না।

আপনি এটি করতে পারেন:

i=$((rint(f)))

তবে সাবধান:

$ echo "$((rint(1e18)))"
1000000000000000000
$ echo "$((rint(1e19)))"
1e+19

আপনি এছাড়াও করতে পারেন:

integer i=$((rint(f)))

তবে এর জন্য পছন্দ করুন zsh:

$ integer i=1e18
$ echo "$i"
1000000000000000000
$ integer i=1e19
$ echo "$i"
-9223372036854775808

সাবধান থাকুন যে ksh93ফ্লোটিং পয়েন্ট গাণিতিক লোকালটিতে দশমিক বিভাজক সেটিংকে সম্মান করে (যদিও ,অন্যথায় গণিত অপারেটর ( $((1,2))কোনও ফরাসি / জার্মানিতে 6/5 হবে ... স্থানীয় এবং এটি $((1, 2))একটি ইংরেজি লোকালে 2) ।

যশ

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

$ echo "$((0.237e2 | 0))"
23
$ echo "$((1e19))"
-9223372036854775808

yash আউটপুটে লোকেলের দশমিক বিভাজককে সম্মান করে, তবে এর গাণিতিক অভিব্যক্তিতে ভাসমান পয়েন্ট আক্ষরিক ধ্রুবকগুলির জন্য নয়, যা বিস্ময়ের কারণ হতে পারে:

$ LC_ALL=fr_FR.UTF-8 ./yash -c 'a=$((1e-2)); echo $(($a + 1))'
./yash: arithmetic: `,' is not a valid number or operator

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

var=$((10.3)) # and not var=10.3
... "$((a + 0.1))" # and not "$(($a + 0.1))".

printf '%.0f\n' "$((10.3))" # and not printf '%.0f\n' 10.3

int=${float%.*}আমার বাশ (সংস্করণ 3.2.57 (1) -রিলিজ) স্ক্রিপ্টটিতে একটি ম্যাক (সংস্করণ 10.13.4 (17E199)) এ খুব ভালভাবে কাজ করেছে।
তেলামন এজিস্টস

আপনিই প্রথম সূত্র গনুহ ব্যাশ 4.4.19 যেমন মধ্যে ব্যর্থ হলে: `` $ echo $ সর্বাধিক 32,800 $ printf, -v int- এ% .0f "$ সর্বাধিক" ব্যাশ: printf,: 32,800: অবৈধ সংখ্যা ``
Luis de সুসা

@ LuísdeSousa, আপনার স্থানীয় সম্ভবত ,দশমিক মূলত হিসাবে আছে । সম্পর্কে বিভাগটি দেখুনLC_ALL=C
স্টাফেন চেজেলাস

মনে রাখবেন যে এই উত্তরটি একটি পৃথক প্রশ্নের জবাব দেয়: বিন্দুর পরে কীভাবে অঙ্কগুলি সরিয়ে নেওয়া হবে তা জিজ্ঞাসা করা হয়নি যা: পূর্ণসংখ্যায় ভাসা করার সঠিক উপায় কী
ইসহাক

এই পদ্ধতিটি কোনও সংখ্যক বিটের ফ্লোটে প্রয়োগ করা উচিত? এটি 23 বিট বা 128 বিট ম্যান্টিসার ভাসমানের জন্য কি একই রকম হওয়া উচিত?
ইসহাক

21

bc - একটি নির্বিচারে নির্ভুলতা ক্যালকুলেটর ভাষা

int (ভাসা) এর মতো দেখতে হবে:

$ echo "$float/1" | bc 
1234

আরও ভাল করে গোল করতে:

$ echo "($float+0.5)/1" | bc 

উদাহরণ:

$ float=1.49
$ echo "($float+0.5)/1" | bc 
1
$ float=1.50
$ echo "($float+0.5)/1" | bc 
2

4
কিন্তু float=-2; echo "($float+0.5)/1" | bcদেয় -1
স্টাফেন চেজেলাস

2
এটিকে বৃত্তাকারে + ইনফের দিকে ডাকা হয়। এটি চারটি সম্ভাব্য উপায়গুলির মধ্যে একটি ।

5

পূর্ববর্তী জমা দেওয়া উত্তর প্রায় সঠিক ছিল: "আপনি এটি করতে পারেন:

float=1.23
int=${float%.*}

তবে এটি আপনাকে নিকটতম পূর্ণসংখ্যার পরিবর্তে ভগ্নাংশটি সরিয়ে ফেলবে এবং এটি 1.2e9 বা .12 এর মতো $ ভাসমান মানের জন্য কাজ করবে না ... "

শুধু ব্যবহার ${float%%.*}

echo ${float%%.*}
1

3

খুব সহজ একটি হ্যাকি

function float_to_int() { 
  echo $1 | cut -d. -f1    # or use -d, if decimals separator is ,
}

নমুনা আউটপুট

$ float_to_int 32.333
32
$ float_to_int 32
32

এটি ব্যবহার করা সম্ভব হবে sed, তবে cutসমাধানটি সহজ। আমি পছন্দ sedবা cutতারা এই প্রোগ্রামটিতে চেয়ে এমবেডেড লক্ষ্যমাত্রা সম্পর্কে আরো পাওয়া যায় awk(যা এখনও মাধ্যমে খুবই সাধারণ busyboxচেয়ে bc)।
পেভিক

0

সম্পর্কিত:

  1. কীভাবে বিশৃঙ্খলায় পূর্ণসংখ্যায় ভাসা যায় ,
  2. কিভাবে শেল মধ্যে ভাসমান পয়েন্ট সংখ্যা বৃত্তাকার?

পরিপূরক @ স্টাফেন চ্যাজেলাস awk উত্তর:

float_to_integer_rounding_nearst() {
    awk 'BEGIN{for (i=1; i<ARGC;i++) printf "%.0f", ARGV[i]}' "$@";
}

float_to_integer_rounding_floor() {
    awk 'BEGIN{for (i=1; i<ARGC;i++) printf "%d", int( ARGV[i] )}' "$@";
}

আমার জাগ্রত অবস্থার পরে, একের পরেরটি শূন্যের দিকে, মাইনাস অনন্তের দিকে নয় ("তল" হিসাবে এটি বোঝানো যেতে পারে)। এছাড়াও, প্রথম রাউন্ডগুলি সমান সংখ্যায় অর্ধেক হয়ে যায়। আমি নিশ্চিত নই যে এটি বাশের কাজ থেকে আলাদা কি printfনা, বা বিল্টিনের চেয়ে বিশ্রী অগ্রাধিকারের কোনও কারণ আছে কিনা printf
ইলকচাচু
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.