Archiv verlassen und diese Seite im Standarddesign anzeigen : Formatierung von Zahlen
Hi Leutz,
ich möchte gerne eine Variable $start formatieren.
Der Wert der $start Variable ist z.b. 1000000.00
Nun will ich aber das diese Zahl so formatiert wird das man den Preis besser erkennen kann. Also anstatt 1000000.00 halt 1.000.000.00
Wie kann ich denn da am besten vor gehen?
Hab zwar von Php ein wenig Ahnung aber Perl komm ich nicht klar
Ich hab auch schon bei Google gesucht wie ein Idiot - und hab was von sprintf() gelesen.
Kann mir da wer helfen?
Danke im vorraus
eViL_oNe
30.07.2005, 19:26
es wäre mir neu, dass sich Tausender-Trennzeichen mit sprintf() erzeugen lassen.
das Vorgehen sollte allerdings recht simpel sein:
1. Nachkommaanteil ermitteln
2. Vorkommaanteil, solange ganzzahlig durch 1000 teilen, bis dieser gleich 0 ist - Rest der Division ergibt einen Tausender-Block
3. Tausenderblöcke mit "." verbinden, Nachkommteil mit "," anhängen
kannst du mir da mal bitte ein code beispiel geben?
eViL_oNe
31.07.2005, 16:31
#!/usr/bin/perl
use strict;
sub groupThousands {
my ($value) = @_;
my $afterComma = sprintf( "%02d", int( ( $value - int( $value ) ) * 100 ) );
my $beforeComma = int( $value );
my @thousandGroups = ();
my $ret;
if ( $beforeComma > 0 )
{
while ( $beforeComma > 0 )
{
unshift( @thousandGroups, $beforeComma % 1000 );
$beforeComma = int( $beforeComma / 1000 );
}
$ret = join(".", @thousandGroups) . "," . $afterComma;
}
else
{
$ret = "0," . $afterComma;
}
return $ret;
}
print groupThousands( $ARGV[0] );
tatsächlich sprintf()
Vielen Dank :) Ich werds mal versuchen einzubauen hoffe es gelingt
Werd mich nochmal dazu äußern
butterkeks
31.07.2005, 17:46
etwas kompakter:
$n = 1000000.10;
# ...
print join(".", reverse(reverse(int($n)) =~ /(.{1,3})/g)) . "," . int(($n - int($n)) * 100)
mir fiel jetzt nicht mehr ein, wie man besser an den hinteren Teil des Kommas kommt, also hab ich evil's Variante gewählt
sehr geil :) -> Ich probier dann mal die kurze Variante
Mehr als das was du da geschrieben hast brauch ich nicht oder muss ich was von evil da übernehmen?
butterkeks
31.07.2005, 19:07
nein, das sollte so funktionieren (hab es eben in der perl shell ausprobiert, aber wenn es dennoch Probs gibt, dann melde dich)
sag mir wie ich das in den code einbaue und ich ernenne dich zum Helfer des Monats :)
sub print_home_featured {
use Benchmark;
$_starttime2 = new Benchmark();
my $displaytop="";
if ($config{'mainview_top'} eq '1') {
my $highbid;
my $itemnum;
my $itemtitle;
my $itemrand;
my $itemqty;
my $itemclose;
my $itemopen;
my $image;
my $numbids;
my %tempitemhash;
my @itemorder;
my $icons;
my $db_query;
my $color = "auktion2";
my $testt;
$displaytop = "<tr><td width=100% align=center valign=top><br><b><a href=$config{'script_dir'}/browse2.pl?action=featured>Top-Inserate</a></b><br><br></td></tr><tr><td width=100%><TABLE ALIGN=CENTER VALIGN=TOP CELLSPACING=0 CELLPADDING=3 WIDTH=100% style='border: 1px solid #C5C5C5; border-left: 0px; border-top:0px;'>";
if ($config{'mainview_random'} eq '1') {
$db_query = "SELECT itemnum,title,quantity,close,image1,start,location, MAX(RAND()) AS sort FROM Items WHERE closef <> '1' AND featured='yes' GROUP BY itemnum ORDER BY sort LIMIT 5";
$sqlqueries++;
} else {
$db_query = "SELECT itemnum,title,quantity,close,image1,start,location, FROM Items WHERE closef <> '1' AND featured='yes' ORDER BY close LIMIT 0,5";
$sqlqueries++;
}
my $count;
$dbh=$db->prepare($db_query);
$dbh->execute();
my $dataexists1 = $dbh -> rows;
while (($itemnum,$itemtitle,$itemqty,$itemclose,$image,$start,$location,$itemrand,) = $dbh->fetchrow_array()) {
@{$tempitemhash{$itemnum}} = ($itemtitle,$itemqty,$itemclose,$image,$start,$location,$itemrand);
push (@itemorder, $itemnum);
}
foreach $itemnum (@itemorder) {
($itemtitle,$itemqty,$itemclose,$image,$start,$location,$itemrand) = @{$tempitemhash{$itemnum}};
$dbh=$db->prepare("SELECT COUNT(*) FROM Bids WHERE biditem=" . int($itemnum));
$sqlqueries++;
$dbh->execute();
($numbids) = $dbh->fetchrow_array();
my $timeremain = UltimateAuction::time_remain($itemclose);
$highbid = UltimateAuction::get_high_bid($itemnum,$itemqty,$db);
$count++;
if (length($itemtitle) > 50) {
$itemtitle = substr $itemtitle, 0, 50;
$itemtitle.="...";
}
$icons = "";
$icons .= $config{'hot_item_icon'} if $numbids >= $config{'hot_item_bids'};
$icons .= $config{'dutch_item_icon'} if $itemqty > 1;
my $imageview;
if (!$image) {
$imageview ="<td width=135><A HREF=http://www.domain.com/im/item.php?do=show&&item=$itemnum><img src=$config{'aucimages'}/nopic.jpg width=135 height=80 border=1></a>";
} else {
$imageview ="<td width=135><A HREF=http://www.domain.com/im/item.php?do=show&&item=$itemnum><img src=$image width=135 height=80 border=1></a>";
}
my $underscore="_";
my $imagenumber = "1";
if (-e "$config{'image_upload_dir'}/thumbs/100/$itemnum$underscore$imagenumber.gif") {
$imageview = "<td width=135><A HREF=http://www.domain.com/im/item.php?do=show&&item=$itemnum><img src=$config{'image_upload_url'}/thumbs/100/$itemnum$underscore$imagenumber.gif border=1></a>";
}
if (-e "$config{'image_upload_dir'}/thumbs/100/$itemnum$underscore$imagenumber.jpg") {
$imageview = "<td width=135><A HREF=http://www.domain.com/im/item.php?do=show&&item=$itemnum><img src=$config{'image_upload_url'}/thumbs/100/$itemnum$underscore$imagenumber.jpg border=1></a>";
}
if (-e "$config{'image_upload_dir'}/thumbs/100/$itemnum$underscore$imagenumber.jpeg") {
$imageview = "<td width=135><A HREF=http://www.domain.com/im/item.php?do=show&&item=$itemnum><img src=$config{'image_upload_url'}/thumbs/100/$itemnum$underscore$imagenumber.jpeg border=1></a>";
}
if (-e "$config{'image_upload_dir'}/thumbs/100/$itemnum$underscore$imagenumber.png") {
$imageview = "<td width=135><A HREF=http://www.domain.com/im/item.php?do=show&&item=$itemnum><img src=$config{'image_upload_url'}/thumbs/100/$itemnum$underscore$imagenumber.png border=1></a>";
}
$displaytop .= "<TR>$imageview</td><TD width=100%><A HREF=http://www.domain.com/im/item.php?do=show&&item=$itemnum><b>Inserat Nr.: $itemnum</b><br>Ort: $location<br>$itemtitle<br><b>Preis: $start $config{'currency'}</b></A></TD></TR>\n";
if ($color eq "auktion1") {
$color = "auktion2";
} else {
$color = "auktion1";
}
}
if ($count <= 0) {
$displaytop .= "<TR VALIGN=TOP><TD VALIGN=TOP COLSPAN=3 CLASS=auktion2 ALIGN=CENTER><b>Keine TOP-Immobilien vorhanden</b></TD></TR>";
}
$displaytop .= "";
$displaytop .= "</TABLE></td></tr>";
}
$_endtime2 = new Benchmark();
$timediff2 = timediff($_endtime2,$_starttime2);
$benchmarktop = "<br>TOP: " . timestr($timediff2,"auto");
if ($dataexists = 0) {
$displaytop= "";
}
return $displaytop;
}
Da wo die $start variable rot ist im code soll der Preis ausgegeben werden
eViL_oNe
01.08.2005, 19:45
uuui, da hält man sich schon für einen Quasi-Perl-Experten, und da kommt jemand mit einem Codegerüst, dessen Sinn sich mir nicht sofort erschließt :D
leider funzt deine Variante nicht ganz:
1. die Tausendergruppen sind verdreht (aus 12345678 wird 21.543.876)
2. die Nachkommastellen werden nicht auf 2 formattiert (eigentlich banal)
lässt man beide reverse() weg, ist die Reihenfolge der Tausendergruppen und die Zahlenreihenfolge innerhalb einer Gruppe ok, allerdings ist die letzte Gruppe uU. nicht ganz aufgefüllt statt der ersten
(z.B. 123.456.78 statt 12.345.678)
da ich nie ein guter 1-Zeilen-Perl-Coder war, fällt mir auch keine Lösung ein ausser dieser:
#!/usr/bin/perl
use strict;
sub groupThousands {
my ( $value ) = @_;
my @groups = reverse(reverse(int($value)) =~ /\d{1,3}/g);
foreach my $group( @groups )
{
$group = reverse( $group );
}
return join(".", @groups) . "," . sprintf( "%02d", int(($value - int($value)) * 100));
}
print groupThousands( $ARGV[0] );
eViL_oNe
01.08.2005, 19:48
sag mir wie ich das in den code einbaue und ich ernenne dich zum Helfer des Monats :)
ersetze $start durch " . &groupThousands( $start ) . " und schon sollte es gehen
die Funktion musst du dann natürlich in deinen Code übernehmen :)
Aber die $start variable wird doch erst aus der mysql datenbank geladen.
Woher soll die neue "sub" den eigentlich Preis bekommen?
Ich versuchs einfach mal...
1.400.000,00 € wird nun als 1.400.0,00 € ausgegeben.
ansonsten geht es aber - nur die zwei "0"len fehlen ...
was muss ich da nun ändern das sie richtig angezeigt wird?
Sorry das ich so stress ^^
eViL_oNe
01.08.2005, 22:56
mein lokales Testprogramm gibt das schon richtig aus
welche Variante der sub benutzt du? *g*
okay es funzt - vielen dank an alle Beteiligten
eViL_oNe
01.08.2005, 23:36
sub groupThousands2 {
my ($value) = @_;
my $afterComma = sprintf( "%02d", int( ( $value - int( $value ) ) * 100 ) );
my $beforeComma = int( $value );
my @thousandGroups = ();
my $ret;
if ( $beforeComma > 0 )
{
while ( $beforeComma > 0 )
{
unshift( @thousandGroups, sprintf( "%03d", $beforeComma % 1000 ) );
$beforeComma = int( $beforeComma / 1000 );
}
$thousandGroups[0] = int( $thousandGroups[0] );
$ret = join(".", @thousandGroups) . "," . $afterComma;
}
else
{
$ret = "0," . $afterComma;
}
return $ret;
}
habe natürlich vergessen, jede Tausendergruppe auf 3 Stellen zu formattieren ;)
oder du benutzt Variante 2 von mir, die einen Bugfix von butterkeks' Code darstellt, die macht es richtig ;)
butterkeks
01.08.2005, 23:53
1. die Tausendergruppen sind verdreht (aus 12345678 wird 21.543.876)
2. die Nachkommastellen werden nicht auf 2 formattiert (eigentlich banal)
lässt man beide reverse() weg, ist die Reihenfolge der Tausendergruppen und die Zahlenreihenfolge innerhalb einer Gruppe ok, allerdings ist die letzte Gruppe uU. nicht ganz aufgefüllt statt der ersten
(z.B. 123.456.78 statt 12.345.678)
da ich nie ein guter 1-Zeilen-Perl-Coder war, fällt mir auch keine Lösung ein ausser dieser:
[...]
stimmt, das ist mir garnicht aufgefallen; Danke!
um es bei einer Zeile zu belassen, kann man auch ein map() dazwischen klemmen:
print join(".", map({ $_ = reverse($_) } reverse(reverse(int($n)) =~ /(.{1,3})/g))) . "," . sprintf( "%02d", int(($value - int($value)) * 100));
das wird jetzt aber echt schon etwas zu brutal (und sieht zwar beeindruckend aus, wird im Endeffekt aber wohl langsamer laufen, als die allererste Variante. Wenn du dein Programm also nicht als Kunstwerk ansiehst, würde ich vom Einzeiler abraten)
vBulletin® v3.8.6, Copyright ©2000-2012, Jelsoft Enterprises Ltd.