2010-04-21 11 views
18

Potrzebuję zaprojektować funkcję zwracania liczb ujemnych bez zmian, ale powinien dodać znak + na początku numeru, jeśli już nie jest obecny.Jak przedrostek liczby dodatniej z plusa w PHP

Przykład:

Input  Output 
---------------- 
+1   +1 
1   +1 
-1   -1 

Będzie się tylko wejście numerycznej.

function formatNum($num) 
{ 
# something here..perhaps a regex? 
} 

Funkcja ta będzie nazywany kilka razy w echo/print więc im szybciej tym lepiej.

Aktualizacja:

Dziękuję wszystkim za odpowiedzi. Muszę powiedzieć, że rozwiązanie oparte na sprintf jest naprawdę szybkie.

+1

Co oznacza "ve" i "ve" oznacza? –

+0

Joachim, przepraszam, nie wiedziałem, że są to niestandardowe krótkie przedstawienia. – user318466

Odpowiedz

53

Można użyć wyrażenia regularnego jak:

function formatNum($num){ 
    return preg_replace('/^(\d+)$/',"+$1",$num); 
} 

Ale chciałbym zaproponować nie użyciu regex dla takiej banalnej rzeczy. Jej lepiej, aby korzystanie z sprintf tutaj:

function formatNum($num){ 
    return sprintf("%+d",$num); 
} 

Od PHP Manual for sprintf:

opcjonalnie podaną znak, że zmusza znak (- lub +) do wykorzystania na liczby. Domyślnie tylko znak jest użyty na numerze, jeśli jest ujemny. Ten specyfikator wymusza liczby dodatnie, aby dołączyć znak + i został dodany w PHP 4.3.0.

+7

+1 dla 'sprintf' (zastanawiałem się, dlaczego nikt nie zasugerował tego od samego początku;) ale wtedy byłeś szybszy ode mnie :-D) –

+1

+1 dla sprintf również –

+0

unicornaddict: dlaczego nie używać regex? Słyszałem, że są potężni. Czy nie są? – user318466

5
function formatNum($num) { 
    return ($num>0)?'+'.$num:$num; 
} 
+2

Jeśli przekażę +1, to zwróci ++ 1 :( – user318466

+0

Następnie odrzuć do int. –

+0

jeśli przekażesz +1, to zwróci +1. Zwraca ++ 1, jeśli przekazałeś mu "+1" jako ciąg Jednak preferuję metodę sprintf UnicornAddict's: –

2
function formatNum($num) { 
    $num = (int) $num; // or (float) if you'd rather 
    return (($num >= 0) ? '+' : '') . $num; // implicit cast back to string 
} 
1

Rozwiązanie sprintf dostarczone przez @unicornaddict jest bardzo miły i prawdopodobnie najbardziej elegancki sposób, aby przejść. Pomyślałem, że i tak dostarczę alternatywę. Nie jestem pewny, jak mierzą w prędkości.

// Non float safe version 
function formatNum($num) { 
    return (abs($num) == $num ? '+' : '') . intval($num); 
} 

// Float safe version 
function formatNum($num) { 
    return 
     (abs($num) == $num ? '+' : '') 
     . (intval($num) == $num ? intval($num) : floatval($num)); 
} 

// Float safe version, alternative 
function formatNum($num) { 
    return 
     (abs($num) == $num ? '+' : '') 
     // Add '1' to $num to implicitly cast it to a number 
     . (is_float($num + 1) ? floatval($num) : intval($num)); 
} 
+0

Lub: Zamiast 'intval()', just 'return (((string) abs ($ num)) === $ num) ? '+'. $ num: $ num; '- chociaż to może działać niezawodnie tylko dla liczb całkowitych? [Paramicznie mam rację, gosh.] – pinkgothic

+0

Problem nie występuje w części porównawczej, ale raczej w części powrotnej. , ale jak wspomniałeś, będzie działać tylko dla liczb całkowitych.Modyfikowanie do pracy dla elementów pływających również byłoby trywialne, ale może po prostu zademonstrować, dlaczego 'sprintf' jest lepszym wyborem na początek. –

+0

Zgoda na' sprintf'! nie jestem pewien, czy zmodyfikowanie go do pracy z pływakami byłoby trywialne gh, ciąg może nie reprezentować float, który może być przechowywany jako, no dobrze, w końcu, a następnie rzutowanie z float na string dawałoby różnicę tam, gdzie jej nie ma? – pinkgothic

1

Proste rozwiązanie polega na użyciu specyfikatora formatu w funkcji printf().

Na przykład

$num1=2; 
$num2=-2; 
printf("%+d",$num1); 
echo '<br>'; 
printf("%+d",$num2); 

daje wyjście

+2 
-2 

W twoim przypadku

function formatNum($num){ 
    return printf("%+d",$num); 
} 
Powiązane problemy