Schrift
[thread]6461[/thread]

Floor auch für Minuswerte?



<< |< 1 2 >| >> 14 Einträge, 2 Seiten
silbersteine
 2004-08-05 02:03
#85379 #85379
User since
2003-08-18
27 Artikel
BenutzerIn
[Homepage] [default_avatar]
Hallo,

ich habe eine kleine Subroutine, die aus einem Minutenwert eine Stundenangabe erzeugen soll (also z.B. "4:35"). Das funktioniert auch ganz gut, allerdings nur bei positiven Werten. Übergebe ich allerdings einen negativen Wert (z.B. -440 Minuten), dann gibt die Routine statt "-7:20" dann "-8:40" aus. Klar: Die Funktion Floor rundet generell ab. Ich frage mich jetzt gerade, wie ich das am Elegantesten löse, ohne mehrere If-Verschachtelungen zu bauen. Gibt es vielleicht eine Rundungsfunktion, die auch Minuswerte berücksichtigt und dann entsprechend nach oben rundet (aber eben bei positiven Werten nach unten)?

Code: (dl )
1
2
3
4
5
6
7
sub clock {
my $minutes = shift;
my $hh = floor($minutes/60);
my $rest = $minutes - $hh*60;
if (length($rest) == 1) {$rest = "0".$rest}
return "$hh:$rest";
}
Viele Grüße aus Calberlah

Der SilberStein

<a href="http://www.skriptoase.de/">www.skriptoase.de</a>

# "It's all very perlish" (L.Wall)
ptk
 2004-08-05 02:11
#85380 #85380
User since
2003-11-28
3645 Artikel
ModeratorIn
[default_avatar]
int?
Crian
 2004-08-05 02:22
#85381 #85381
User since
2003-08-04
5872 Artikel
ModeratorIn
[Homepage]
user image
Die Funktion floor (geschrieben als eckige Klammern ohne den oberen Querbalken) aus der Mathematik liefert immer die größte ganze Zahl, die kleiner gleich dem Argument ist.

floor(5.423) -> 5
floor(-17.53) -> -18

Die Funktion int() schneidet einfach die Nachkommestellen ab. Wahrscheinlich ist das das, was Du willst.

int(5.423) -> 5
int(-17.53) -> -17

Edit: Im Grunde genommen hat ptk mit "int?" genau das selbe gesagt, ich hab das nur nochmal etwas ausgeschmückt ;-)

Edit2: Dann gibts auch noch ceil: es wird die kleinste ganze Zahl, die größer gleich dem Argument ist, zurückgeliefert:

ceil(5.423) -> 6
ceil(-17.53) -> -17
\n\n

<!--EDIT|Crian|1091658365-->
s--Pevna-;s.([a-z]).chr((ord($1)-84)%26+97).gee; s^([A-Z])^chr((ord($1)-52)%26+65)^gee;print;

use strict; use warnings; Link zu meiner Perlseite
renee
 2004-08-05 09:28
#85382 #85382
User since
2003-08-04
14371 Artikel
ModeratorIn
[Homepage] [default_avatar]
Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#! /usr/bin/perl

use strict;
use warnings;

my $var =  -440;
print "renee:\t ",clock_renee($var),"\n";
print "silbersteine: ",clock_silbersteine($var),"\n";

sub clock_renee {
   my $minutes = shift;
   my $hh = int $minutes/60;
   $minutes *=  -1 if($minutes < 0);
   my $rest = $minutes % 60;
   $rest = sprintf("%02d",$rest);
   return "$hh:$rest";
}

sub clock_silbersteine{
   my $minutes = shift;
   my $hh = int($minutes/60);
   my $rest = $minutes - $hh*60;
   if (length($rest) == 1) {$rest = "0".$rest}
   return "$hh:$rest";
}


Ausgabe:
Quote
~ 7> perl clock.pl
renee:   -7:20
silbersteine: -7:-20
\n\n

<!--EDIT|renee|1091683748-->
OTRS-Erweiterungen (http://feature-addons.de/)
Frankfurt Perlmongers (http://frankfurt.pm/)
--

Unterlagen OTRS-Workshop 2012: http://otrs.perl-services.de/workshop.html
Perl-Entwicklung: http://perl-services.de/
Dubu
 2004-08-05 20:32
#85383 #85383
User since
2003-08-04
2145 Artikel
ModeratorIn + EditorIn

user image
[quote=silbersteine,05.08.2004, 00:03]
Code: (dl )
1
2
3
4
5
6
7
sub clock {
    my $minutes = shift;
    my $hh = floor($minutes/60);
    my $rest = $minutes - $hh*60;
    if (length($rest) == 1) {$rest = "0".$rest}
    return "$hh:$rest";
}
[/quote]
Beide Methoden liefern ein falshces Ergebnis, wenn die Zeit negativ und unterhalb einer Stunde liegt (-60 < Argument < 0), weil es numerisch kein "-0" gibt.

Ich halte es fuer besser, das Vorzeichen separat zu halten:
Code: (dl )
1
2
3
4
5
6
7
sub clock {
   my $minutes = shift;
   my $sign = ($minutes >= 0);
   my $hh = int($minutes/60);
   my $rest = abs($minutes - $hh*60);
   return sprintf ("%s%d:%02d", ($sign ? '' : '-'), $hh, $rest);
}
silbersteine
 2004-08-06 01:29
#85384 #85384
User since
2003-08-18
27 Artikel
BenutzerIn
[Homepage] [default_avatar]
Hallo,

habt vielen Dank! Das scheint zu funktionieren! Nur einem Phänomen bin ich noch nicht auf die Spur gekommen: Bei -440 Minuten bekomme ich "--7:20", also mit zwei Minuszeichen. Hintergrund: Ich rufe die Funktion so auf:

Code: (dl )
print "Überstunden = ".clock($jobsum-$skalars{'stdtime'});


In dem Fall enthält $skalars{'stdtime'} = 440 Minuten (also die Standardarbeitszeit) und $jobsum = 0 (also gar nicht gearbeitet). Wie kommt nun das doppelte Minuszeichen zustande und wie kann man das verhindern? Habt ihr eine Ahnung?
Viele Grüße aus Calberlah

Der SilberStein

<a href="http://www.skriptoase.de/">www.skriptoase.de</a>

# "It's all very perlish" (L.Wall)
renee
 2004-08-06 01:42
#85385 #85385
User since
2003-08-04
14371 Artikel
ModeratorIn
[Homepage] [default_avatar]
Poste mal, welchen Code Du jetzt nimmst...
OTRS-Erweiterungen (http://feature-addons.de/)
Frankfurt Perlmongers (http://frankfurt.pm/)
--

Unterlagen OTRS-Workshop 2012: http://otrs.perl-services.de/workshop.html
Perl-Entwicklung: http://perl-services.de/
silbersteine
 2004-08-06 01:59
#85386 #85386
User since
2003-08-18
27 Artikel
BenutzerIn
[Homepage] [default_avatar]
Den letzten von Dubu:

Code: (dl )
1
2
3
4
5
6
7
sub clock {
my $minutes = shift;
my $sign = ($minutes >= 0);
my $hh = int($minutes/60);
my $rest = abs($minutes - $hh*60);
return sprintf ("%s%d:%02d", ($sign ? '' : '-'), $hh, $rest);
}
Viele Grüße aus Calberlah

Der SilberStein

<a href="http://www.skriptoase.de/">www.skriptoase.de</a>

# "It's all very perlish" (L.Wall)
esskar
 2004-08-06 02:18
#85387 #85387
User since
2003-08-04
7321 Artikel
ModeratorIn

user image
wo er recht hat, hat er recht :)

Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
D:\Eigene Dateien\Entwicklung\RFC>perl
sub clock {
my $minutes = shift;
my $sign = ($minutes >= 0);
my $hh = int($minutes/60);
my $rest = abs($minutes - $hh*60);
return sprintf ("%s%d:%02d", ($sign ? '' : '-'), $hh, $rest);
}
$jobsum=0;
$skalars{'stdtime'}=440;
print "Überstunden = ".clock($jobsum-$skalars{'stdtime'});
^Z
Überstunden = --7:20


bugfix:

Code: (dl )
1
2
3
4
5
6
sub clock {
my $minutes = shift;
my $hh = int($minutes/60);
my $rest = abs($minutes - $hh*60);
return sprintf ("%d:%02d", $hh, $rest);
}
renee
 2004-08-06 09:33
#85388 #85388
User since
2003-08-04
14371 Artikel
ModeratorIn
[Homepage] [default_avatar]
Damit besteht aber immer noch das Problem -60 < $minutes < 0
Beispiel -42 ergibt bei Dir 0:42

Damit sollte es aber gehen:
Code: (dl )
1
2
3
4
5
6
7
8
sub clock_bugfix {
my $minutes = shift;
my $sign = ($minutes >= 0);
my $hh = int($minutes/60);
my $rest = abs($minutes - $hh*60);
$hh *= -1 if($hh < 0);
return sprintf ("%s%d:%02d", ($sign ? '' : '-'), $hh, $rest);
}
OTRS-Erweiterungen (http://feature-addons.de/)
Frankfurt Perlmongers (http://frankfurt.pm/)
--

Unterlagen OTRS-Workshop 2012: http://otrs.perl-services.de/workshop.html
Perl-Entwicklung: http://perl-services.de/
<< |< 1 2 >| >> 14 Einträge, 2 Seiten



View all threads created 2004-08-05 02:03.