среда, 27 февраля 2013 г.

Династия Романовых 400

Женщины дома Романовых 400

Великий князь Константин Константинович, внук Николая I, вошел в историю русской литературы конца XIX в. под псевдонимом К.Р.

Про КР http://www.prlib.ru/history/Pages/Item.aspx?itemid=1096

понедельник, 25 февраля 2013 г.

Homo soveticus

Этот этнофолизм достался русским от соседей — «прибалтов», точнее эстонцев. «Тыбла» пришло от обращения «ты, бл.». Так первоначально в Эстонии называли бойцов Красной Армии в 1918-1920, 1940-1941 и 1944 гг. Сравнительно малочисленного русского меньшинства в довоенной независимой Эстонии это обращение сначала не касалось. Во время советской власти это выражение начало использоваться только среди коренного населения. После обретения свободы слова и независимости в 1991 году прочно вошло в лексикон, как презрительное и оскорбительное прозвище русскоговорящих жителей страны, особенно тех, которые не владеют местным языком. Совет по СМИ считает, что выражение «tibla» в первую очередь используется как обозначение Homo soveticus (человека советского).

http://russian7.ru/2012/06/7-prozvishh-kotorye-poluchili-russkie/

вторник, 12 февраля 2013 г.

Чудеса округления sprintf

Все началось с числа  4.4525. При округлении до 3-его знака ожидалось получить 4.453, однако Perl'овый sprintf настойчиво возвращал 4.452.

Далее прочитал следующие правила округления:
http://ibrain.kz/mod/book/view.php?id=211&chapterid=966

Ага, оно действительно подтверждается следующими выходами:

$ perl
foreach $i (0.5, 1.5, 2.5, 3.5, 4.5) {
     printf "%f -> %.0f\n", $i, $i;
}

Output: 0.500000 -> 0
1.500000 -> 2
2.500000 -> 2
3.500000 -> 4
4.500000 -> 4
Резюме: допустимо, т.к. объяснимо))

тогда вот это как объяснить?!
$ perl
printf "%f -> %.3f\n", 4.45*5, 4.45*5;

Output: 4.450500 -> 4.450
4.451500 -> 4.452
4.452500 -> 4.452
4.453500 -> 4.454
4.454500 -> 4.455
4.455500 -> 4.455
4.456500 -> 4.457
4.457500 -> 4.457
4.458500 -> 4.458
4.459500 -> 4.460
Резюме: непонятно почему так

$ perl
printf "%f -> %.3f\n", 4.*525, 4.*525;

Output: 4.052500 -> 4.053
4.152500 -> 4.152
4.252500 -> 4.253
4.352500 -> 4.353
4.452500 -> 4.452
4.552500 -> 4.553
4.652500 -> 4.652
4.752500 -> 4.752
4.852500 -> 4.853
4.952500 -> 4.952
Резюме: непонятно почему так

========================================


Теперь добавим наименьшее слагаемое $delta = 1E-12



$ perl
foreach $i (0.5, 1.5, 2.5, 3.5, 4.5) {
     printf "%f -> %.0f\n", $i+$delta, $i+$delta;
}

Output: 0.500000 -> 1
1.500000 -> 2
2.500000 -> 3
3.500000 -> 4
4.500000 -> 5
Резюме: окей

$ perl
printf "%f -> %.3f\n", 4.45*5+$delta, 4.45*5+$delta;

Output: 4.450500 -> 4.451
4.451500 -> 4.452
4.452500 -> 4.453
4.453500 -> 4.454
4.454500 -> 4.455
4.455500 -> 4.456
4.456500 -> 4.457
4.457500 -> 4.458
4.458500 -> 4.459
4.459500 -> 4.460
Резюме: окей

$ perl
printf "%f -> %.3f\n", 4.*525+$delta, 4.*525+$delta;

Output: 4.052500 -> 4.053
4.152500 -> 4.153
4.252500 -> 4.253
4.352500 -> 4.353
4.452500 -> 4.453
4.552500 -> 4.553
4.652500 -> 4.653
4.752500 -> 4.753
4.852500 -> 4.853
4.952500 -> 4.953
Резюме: окей

Таким образом, для sprintf такое добавление малого числа сказывается благотворно на результат округления.

========================================

Написал функцию для работы с положительными числами:

sub rounding ($$) {
    my ($num, $accuracy) = @_;
    $scale = eval "1e+$accuracy";
    return int($num*$scale+0.5)/$scale;
}

print Dumper(rounding(4.4525, 3));
print Dumper(rounding(4.4525e-09, 12));

Output: 4.453
Резюме: окей

####################################################################################################
#  "Nearest" routines (round to a multiple of any number)
#  function from CPAN Math::Round
#
####################################################################################################
#
#  nearest(10, 44)    yields  40
#  nearest(10, 46)            50
#  nearest(10, 45)            50
#  nearest(25, 328)          325
#  nearest(.1, 4.567)        4.6
#  nearest(10, -45)          -50

sub nearest {
 my $half = 0.50000000000008;

 my $targ = abs(shift);
 my @res  = map {
  if ($_ >= 0) { $targ * int(($_ + $half * $targ) / $targ); }
     else { $targ * POSIX::ceil(($_ - $half * $targ) / $targ); }
 } @_;

 return (wantarray) ? @res : $res[0];
}

$ perl
print Dumper(nearest(.001, 4.4525));
Output: 4.452