स्ट्रिंग को गोल करें


10

कुछ दशमलव संख्याओं को बाइनरी फ़्लोट्स के आंतरिक प्रतिनिधित्व के कारण बाइनरी फ़्लोट्स के रूप में ठीक से प्रस्तुत नहीं किया जा सकता है। उदाहरण के लिए: 14.225 को दो दशमलव अंकों में बदलने से 14.23 परिणाम नहीं होता है जैसा कि कोई उम्मीद कर सकता है लेकिन 14.22 में।

अजगर :

In: round(14.225, 2)
Out: 14.22

हालांकि, मान लें कि हमारे पास '14 .225 'के रूप में 14.225 का एक स्ट्रिंग प्रतिनिधित्व है, हमें एक स्ट्रिंग प्रतिनिधित्व के रूप में हमारे वांछित गोलाई '14 .23' को प्राप्त करने में सक्षम होना चाहिए।

इस दृष्टिकोण को मनमाने ढंग से सटीक करने के लिए सामान्यीकृत किया जा सकता है।

संभव अजगर 2/3 समाधान

import sys

def round_string(string, precision):
    assert(int(precision) >= 0)
    float(string)

    decimal_point = string.find('.')
    if decimal_point == -1:
        if precision == 0:
            return string
        return string + '.' + '0' * precision

    all_decimals = string[decimal_point+1:]
    nb_missing_decimals = precision - len(all_decimals)
    if nb_missing_decimals >= 0:
        if precision == 0:
            return string[:decimal_point]
        return string + '0' * nb_missing_decimals

    if int(all_decimals[precision]) < 5:
        if precision == 0:
            return string[:decimal_point]
        return string[:decimal_point+precision+1]

    sign = '-' if string[0] == '-' else '' 
    integer_part = abs(int(string[:decimal_point]))
    if precision == 0:
        return sign + str(integer_part + 1)
    decimals = str(int(all_decimals[:precision]) + 1)
    nb_missing_decimals = precision - len(decimals)
    if nb_missing_decimals >= 0:
        return sign + str(integer_part) + '.' + '0' * nb_missing_decimals + decimals
    return sign + str(integer_part + 1) + '.' + '0' * precision

इसे ऑनलाइन आज़माएं!

उपयोग :

     # No IEEE 754 format rounding
In:  round_string('14.225',2)
Out: '14.23'

     # Trailing zeros
In:  round_string('123.4',5)
Out: '123.40000'

In: round_string('99.9',0)
Out: '100'

    # Negative values
In: round_string('-99.9',0)
Out: '-100'

In: round_string('1',0)
Out: '1'

    # No unnecessary decimal point
In: round_string('1.',0)
Out: '1'

    # No unnecessary decimal point
In: round_string('1.0',0)
Out: '1'

In:  for i in range(8): 
         print(round_string('123456789.987654321',i))
Out: 123456790
     123456790.0
     123456789.99
     123456789.988
     123456789.9877
     123456789.98765
     123456789.987654
     123456789.9876543

कार्य

इनपुट तर्क 1 : एक स्ट्रिंग युक्त

  • कम से कम अंकों एक ( 0, 1, 2, 3, 4, 5, 6,7 , 8, 9),
  • अधिकतम एक दशमलव बिंदु पर (. ) जिसे कम से कम एक अंक से पहले होना चाहिए,
  • एक वैकल्पिक ऋण (- ) पहले चरित्र के रूप में।

इनपुट तर्क २ : एक गैर-नकारात्मक पूर्णांक

उत्पादन : सही ढंग से गोल (बेस 10) स्ट्रिंग

गोलाई = शून्य से आधा दूर

यह एक । बाइट्स की सबसे कम संख्या जीतती है!


@ केविनक्रूजसेन 1) आपको अपने कार्यान्वयन के शरीर में तार से चिपके रहने की आवश्यकता नहीं है और इसे अंतर्निहित गोलाई का उपयोग करने की अनुमति है। दुर्भाग्य से (प्रश्न के लिए) IEEE 754 मानक एक व्यापक रूप से इस्तेमाल किया जाने वाला मानक है और इस प्रकार अंतर्निहित गोलाई वांछित व्यवहार का परिणाम नहीं देगा। 2) ठीक है, सैंडबॉक्स के बारे में पता नहीं था।
मथियास

टीआई-बेसिक: round(A,B5 बाइट्स
जूलियन लाचनीट

1
दूसरे इनपुट तर्क के बारे में: 0एक सकारात्मक पूर्णांक नहीं है, यह "गैर-नकारात्मक" है।
स्टीवी ग्रिफिन

1
मुझे लगता है कि हम जरूरत पड़ने पर ट्रेलिंग शून्य जोड़ते हैं? क्या आप शायद इसके लिए एक परीक्षण मामला जोड़ सकते हैं 123.4 & 5 --> 123.40000? या क्या हम यह मान सकते हैं कि पहले इनपुट में बिंदु के बाद दूसरा इनपुट कभी भी दशमलव की मात्रा से बड़ा नहीं होगा?
केविन क्रूज़सेन

1
@ मैथियास जब तक आप पायथन को जावास्क्रिप्ट के साथ एकीकृत कर सकते हैं (मैंने कभी पायथन को प्रोग्राम नहीं किया है, और मुश्किल से जेएस है, इसलिए मुझे ईमानदारी से पता नहीं है कि यह संभव है) नहीं। लेकिन आप हमेशा अपने परीक्षण कोड के साथ एक कोशिश ऑनलाइन लिंक जोड़ सकते हैं । संपादित करें: इसके अलावा, आमतौर पर कम से कम कुछ दिनों तक इंतजार करना बेहतर होता है जब तक कि आप एक उत्तर स्वीकार नहीं करते हैं।
केविन क्रूज़सेन

जवाबों:


2

एपीएल (डायलॉग) , 4 बाइट्स

Dyalog APL पर्याप्त आंतरिक परिशुद्धता का उपयोग करता है।

⎕⍕⍎⍞

इसे ऑनलाइन आज़माएं!

⍎⍞ स्ट्रिंग इनपुट निष्पादित करें

⎕⍕ संख्यात्मक इनपुट प्राप्त करें और फ़ॉर्मेटिंग के लिए सटीक रूप में उपयोग करें


यह 8 बाइट्स के बजाय 4 क्यों है?
मथियास

@ मैथियास क्योंकि डायलाग एपीएल
एसबीसीएस

5

पर्ल, 22 20 बाइट्स

printf"%.*f",pop,pop

का उपयोग करते हुए:

perl -e 'printf"%.*f",pop,pop' 123456789.987654321 3

यह दादा के कोड का संस्करण है। पिछला:

printf"%*2\$.*f",@ARGV

2
printf"%.*f",pop,popकाम करना चाहिए
दादा

5

PHP, 33 31 बाइट्स

PHP सही ढंग से भी (कम से कम 64 बिट पर) गोल:

printf("%.$argv[2]f",$argv[1]);

कमांड लाइन तर्कों से इनपुट लेता है। के साथ भागो -r

PHP, कोई बिल्ट-इन, 133 बाइट्स

[,$n,$r]=$argv;if($p=strpos(_.$n,46))for($d=$n[$p+=$r],$n=substr($n,0,$p-!$r);$d>4;$n[$p]=(5+$d=$n[$p]-4)%10)$p-=$n[--$p]<"/";echo$n;

इसे ऑनलाइन चलाएं -nrया परीक्षण करें

टूट - फूट

[,$n,$r]=$argv;             // import arguments
if($p=strpos(_.$n,46))      // if number contains dot
    for($d=$n[$p+=$r],          // 1. $d= ($r+1)-th decimal 
        $n=substr($n,0,$p-!$r); // 2. cut everything behind $r-th decimal
        $d>4;                   // 3. loop while previous decimal needs increment
        $n[$p]=(5+$d=$n[$p]-4)%10   // B. $d=current digit-4, increment current digit
    )
        $p-=$n[--$p]<"/";           // A. move cursor left, skip dot
echo$n;

एक अशक्त बाइट काम नहीं करता है; इसलिए मुझे उपयोग करना होगा substr


1
आप 2 बाइट्स को बचाने के "%.$argv[2]f"बजाय लिख सकते हैं "%.{$argv[2]}f"
इस्माइल मिगुएल

4

रूबी 2.3, 12 + 45 = 57

BigDecimalबिल्ट-इन का उपयोग करता है, लेकिन उपयोग करने से पहले इसकी आवश्यकता होती है, जो ध्वज के रूप में करने के लिए सस्ता है।

झंडा: -rbigdecimal

कार्यक्रम:

->(s,i){BigDecimal.new(s).round(i).to_s('f')}

रूबी 2.3 डिफ़ॉल्ट रूप से उपयोग करता है ROUND_HALF_UP


4

जावास्क्रिप्ट (ईएस 6), 44 बाइट्स

n=>p=>(Math.round(n*10**p)/10**p).toFixed(p)

इसे ऑनलाइन आज़माएँ:

const f = n=>p=>(Math.round(n*10**p)/10**p).toFixed(p)

console.log(f('14.225')(2));

[...Array(8).keys()].map(i=>console.log(f('123456789.987654321')(i)))

console.log(f('123.4')(5))


4

पायथन, 114 105 103 96 91 89 बाइट्स

केविन क्रूज़सेन की ओर से 5 बाइट्स को धन्यवाद दिया गया, क्रेज़र को
2 बाइट्स बचाए गए

from decimal import*
d=Decimal
lambda x,y:d(x).quantize(d('0.'[y>0]+'1'*y),ROUND_HALF_UP)

इसे ऑनलाइन आज़माएं!


1
from decimal import *और तीन को हटाना d.4 बाइट्स छोटा है।
केविन क्रूज़सेन

@ केविनक्रूजसेन: धन्यवाद!
एमिग्ना

2
आप भी कर सकते हैं d=Decimalऔर d() जो एक और बचत करेगा 5. (शायद गलत, बहुत नींद)
FMaz

@Krazor: जब तक मैंने गलत नहीं किया तब तक उसने मुझे 2 बाइट्स से बचाया। धन्यवाद!
एमिग्ना

वाह, यही मेरा मतलब है। मेरे नींद के विचारों को वैसे भी छोड़ देगा।
फमाज़

4

आरईएक्सएक्स, 24 बाइट्स

arg n p
say format(n,,p)

चूंकि REXX हमेशा संख्याओं के पाठ प्रतिनिधित्व का उपयोग करता है, संख्याओं का सही गोलाई मुक्त है।

इसे ऑनलाइन आज़माएं!


वाह। भाषा का अच्छा दुरुपयोग।
मैथ्यू रो

क्या REXX में ऑनलाइन कंपाइलर है?
केविन क्रूज़सेन

यह (मुख्य रूप से) एक व्याख्या की गई भाषा है।
14:17


3

BASH, 26 23 21 बाइट्स

bc<<<"scale=$2;$1/1"

प्रयोग

round_string.sh पर सहेजें, chmod + x round_string.sh

./round_string.sh 23456789.987654321 3

संपादित करें: लाइब्रेरी लोड करने की कोई आवश्यकता नहीं है


स्पष्टीकरण: bc मनमाना पूर्वसर्ग का उपयोग करता है, स्केल के दूसरे पैरामीटर के रूप में '<<<' स्केल के मान के साथ यहां एक doc बनाएं और स्केल व्याख्या के लिए 1 पैरामीटर को 1 से विभाजित किया गया है।
१। ’

2
यह 14.22इनपुट के लिए देता है 14.225 2, और नहीं14.23
डिजिटल ट्रॉमा

3

एएचके, 25 बाइट्स

a=%1%
Send % Round(a,%2%)

फिर से मुझे एएचके की अक्षमता के कारण उन कार्यों में सीधे उपयोग करने में असमर्थता है जो एक चर नाम या संख्या को स्वीकार करते हैं। अगर मैं बदलने के aसाथ 1में Roundसमारोह है, यह मान का उपयोग करता 1। अगर मैं कोशिश %1%करता हूं , तो यह पहले तर्क की सामग्रियों को एक चर नाम के रूप में उपयोग करने की कोशिश करता है , जो काम नहीं करता है। एक और चर के रूप में इसे सेट करने के बाद पहले मुझे 6 बाइट की लागत आई।


3

बैच, 390 बाइट्स

@echo off
set s=%1
set m=
if %s:~,1%==- set m=-&set s=%s:~1%
set d=%s:*.=%
if %d%==%s% (set d=)else call set s=%%s:.%d%=%%
for /l %%i in (0,1,%2)do call set d=%%d%%0
call set/ac=%%d:~%2,1%%/5
call set d=00%s%%%d:~,%2%%
set z=
:l
set/ac+=%d:~-1%
set d=%d:~,-1%
if %c%==10 set c=1&set z=%z%0&goto l
set d=%m%%d:~2%%c%%z%
if %2==0 (echo %d%)else call echo %%d:~,-%2%%.%%d:~-%2%%

स्पष्टीकरण। यदि लागू हो तो साइन को निकालने से शुरू होता है। फिर, संख्या को पूर्णांक और अंश अंकों में विभाजित करता है। अंश को अंक n+1से अधिक सुनिश्चित करने के लिए शून्य के साथ गद्देदार किया जाता है nnवें (शून्य अनुक्रमित) अंकों 5 से विभाजित है, और इस प्रारंभिक कैरी है। पूर्णांक और nअंश अंक संक्षिप्त होते हैं, और वर्ण द्वारा वर्ण जोड़ा जाता है। (कैरी रिपल के खिलाफ अतिरिक्त जीरो गार्ड।) कैरी रिप करने के बाद नंबर को रिस्ट्रिक्ट किया जाता है और किसी भी दशमलव बिंदु को डाला जाता है।


3

TI-बेसिक, 53 16 बाइट्स

TI-Basic IEEE का उपयोग नहीं करता है और नीचे दी गई विधि 0-9 (समावेशी) दशमलव पदों के लिए काम करती है।

Prompt Str1,N
toString(round(expr(Str1),N

@JulianLachniet को दिखाने के लिए धन्यवाद कि सीई कैल्स के पास है toString( कमांड है जिसके बारे में मुझे जानकारी नहीं थी (कलर एडिशन calcs OS 5.2 या उच्चतर की आवश्यकता है)।

PS मेरे पास दूसरी पंक्ति थी, sub(Str1,1,N+inString(Str1,".लेकिन तब मुझे एहसास हुआ कि यह बेकार है।


कैसे Nकिया जाता है?
मथायस

@ मैथियास उस टाइपो को पकड़ने के लिए धन्यवाद! मैंने अपने पिछले एडिट के साथ गलती से आखिरी तीन बाइट्स निकाल दिए
टाइमटेक

3

जावा 7, 77 72 71 बाइट्स

<T>T c(T n,int d){return(T)"".format("%."+d+"f",new Double(n+""));}

-1 बाइट थैंक्स टू @cliffroot

72-बाइट उत्तर:

String c(String n,int d){return n.format("%."+d+"f",new Double(n));}

पायथन के विपरीत, जावा पहले से ही सही ढंग से गोल हो जाता है और पहले से ही एक स्ट्रिंग लौटाता है जब आप के String.format("%.2f", aDouble)साथ उपयोग करते हैं2 दशमलव आप चाहते हैं की राशि के साथ बदल दिया।

संपादित करें / नोट: हाँ, मुझे पता है new Float(n)कि 1 बाइट से छोटा है new Double(n), लेकिन जाहिर है कि यह परीक्षण मामलों के लिए विफल रहता है 123456789.987654321डबल बनाम फ्लोट के बारे में यह परीक्षण कोड देखें।

स्पष्टीकरण:

<T> T c(T n, int d){               // Method with generic-T & integer parameters and generic-T return-type (generic-T will be String in this case)
  return (T)"".format("%."+d+"f",  //  Return the correctly rounded output as String
    new Double(n+""));             //  After we've converted the input String to a decimal
}                                  // End of method

टेस्ट कोड:

इसे यहाँ आज़माएँ।

class M{
  static <T>T c(T n,int d){return(T)"".format("%."+d+"f",new Double(n+""));}

  public static void main(String[] a){
    System.out.println(c("14.225", 2));
    System.out.println(c("123.4", 5));
    System.out.println(c("99.9", 0));
    System.out.println(c("-99.9", 0));
    System.out.println(c("1", 0));
    System.out.println(c("1.", 0));
    System.out.println(c("1.0", 0));
    for(int i = 0; i < 8; i++){
      System.out.println(c("123456789.987654321", i));
    }
  }
}

आउटपुट:

14.23
123.40000
100
-100
1
1
1
123456790
123456790.0
123456789.99
123456789.988
123456789.9877
123456789.98765
123456789.987654
123456789.9876543

1
एक बाइट छोटी:<T>T c(T n,int d){return(T)"".format("%."+d+"f",new Double(n+""));}
क्लिफरॉट

2
यह समाधान काम नहीं करता है । हालाँकि उदाहरण संभावित रूप से एक आधा-सम / दूर / 0 अंक का है, फ़्लोटिंग पॉइंट त्रुटियां होती हैं और ओपी ने स्पष्ट किया है कि मनमाना परिशुद्धता का समर्थन किया जाना चाहिए।
सीएडी 97

1
वास्तव में, आप उस उदाहरण के मामलों में असफल हो जाते हैं जिस प्रश्न को आपने यहां पुन: प्रस्तुत किया है: 123456789.987654321, 4होना चाहिए 123456789.9877, नहीं123456789.9876
CAD97

2

पायथन (2/3), 394 बाइट्स

def rnd(s,p):
    m=s[0]=='-'and'-'or''
    if m:s=s[1:]
    d=s.find('.')
    l=len(s)
    if d<0:
        if p>0:d=l;l+=1;s+='.'
        else:return m+s
    e=(d+p+1)-l
    if e>0:return m+s+'0'*e
    o=''
    c=0
    for i in range(l-1,-1,-1):
        x=s[i]
        if i<=d+p:
            if i!=d:
                n=int(x)+c
                if n>9:n=0;c=1 
                else:c=0
                o+=str(n)
            else:
                if p>0:o+=x
        if i==d+p+1:c=int(x)>4
    if c:o+='1'
    return m+''.join(reversed(o))

मनमाना सटीक संख्याओं के लिए काम करता है।


5
अरे, और PPCG में आपका स्वागत है! हालाँकि, यह गोल्फ नहीं है। वहाँ एक है बहुत कुछ खाली स्थान के आप निकाल सकते हैं की। इस साइट पर उत्तर गोल्फ के लिए आवश्यक हैं, क्षमा करें।
R

बस कुछ चीजें (संभावना बहुत अधिक है) ... फ़ंक्शन का नाम एक बाइट हो सकता है। पहली पंक्ति का उपयोग कर सकते हैं s[0]<'0'और स्ट्रिंग गुणा का उपयोग भी कर सकते हैं m='-'*(s[0]<'0'),। बिना किसी ब्लॉक स्टेटमेंट के लाइनों को एक साथ जोड़ा जा सकता है ;(जैसे o='';c=0)। ifलाइन ब्रेक और टैब की आवश्यकता को और कम करने के लिए कुछ बयानों को संभवतः सूची अनुक्रमण द्वारा प्रतिस्थापित किया जा सकता है। अंतिम पंक्ति एक स्लाइस का उपयोग कर सकती है o[::-1], इसके बजाय reversed(o)और ''.joinनिरर्थक है। आप अच्छी तरह से कई returnबयानों की आवश्यकता से बचने के लिए इसे फिर से लिखने में सक्षम हो सकते हैं ।
जोनाथन एलन


2

जावास्क्रिप्ट (ईएस 6), 155 बाइट्स

(s,n)=>s.replace(/(-?\d+).?(.*)/,(m,i,d)=>i+'.'+(d+'0'.repeat(++n)).slice(0,n)).replace(/([0-8]?)([.9]*?)\.?(.)$/,(m,n,c,r)=>r>4?-~n+c.replace(/9/g,0):n+c)

स्पष्टीकरण: स्ट्रिंग को पहले .और n+1दशमलव अंकों को शामिल करने के लिए सामान्यीकृत किया जाता है। अनुगामी अंक, किसी पूर्ववर्ती 9s या .s और किसी पूर्ववर्ती अंक, तब माना जाता है। यदि अंतिम अंक 5 से कम है, तो इसे और किसी भी पूर्ववर्ती प्रक्रिया .को सरलता से हटा दिया जाता है, लेकिन यदि यह 5 से अधिक है, तो 9s को s में बदल दिया जाता है 0और पिछले अंक को बढ़ा दिया जाता है (या यदि पिछले अंक नहीं था तो 1 उपसर्ग किया जाता है)।



1

स्काला, 44 बाइट्स

(s:String,p:Int)=>s"%.${p}f"format s.toFloat

परीक्षा:

scala> var x = (s:String,p:Int)=>s"%.${p}f"format s.toFloat
x: (String, Int) => String = <function2>

scala> x("14.225",2)
res13: String = 14.23

1

आश्चर्य है , 10 बाइट्स

@@fix#1E#0

उपयोग:

@@fix#1E#0

दशमलव परिशुद्धता सेट करें और यदि आवश्यक हो तो अनुगामी शून्य जोड़ें।


क्या इसके लिए कोई TIO है?
मथियास

नहीं वहाँ नहीं है, लेकिन स्थापना बहुत आसान है। सुनिश्चित करें कि आपके पास Node.js (v6 +), और है npm i -g wonderlangwonderआरईपीएल को आग लगाने के लिए कमांड का उपयोग करें , और कोड को पेस्ट करें।
मम्मा फन रोल

1

जे, 22 17 बाइट्स

((10 j.[)]@:":".)

NB.    2    ((10 j.[)]@:":".)   '12.45678'
NB.    12.46 

नियमों की मेरी समझ को सही करने के लिए @Conor O'Brien को धन्यवाद।

t=:4 :'(10 j.x)":".y'

    NB.    Examples
    NB.    4 t'12.45678'
    NB.    12.4568
    NB.    4 t'12.456780'
    NB.    12.4568
    NB.    4 t'12.4567801'
    NB.    12.4568
    NB.    2 t'12.45678'
    NB.      12.46
    NB.    2 t'12.4567801'
    NB.      12.46
    NB.    2 (10 j.[)":". '_12.4567801'
    NB.     _12.46

format    
    x t y
where x is a digit number of decimal places required and y
is the character string containing the value to be rounded.

दशमलव दशमलव के बाद अंकों की संख्या को लेने के लिए आपको चुनौती की आवश्यकता होती है, न कि दशमलव के राउंड की, न कि सटीकता के N बिंदुओं की। जैसे, इसके बदले 2 t '1234.456'देना चाहिए1234.466 t '1234.456'
कोनोर ओ ब्रायन
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.