Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Потрепаться";
Текущий архив: 2004.06.06;
Скачать: [xml.tar.bz2];

Вниз

Преобразование числа в рубли и копейки   Найти похожие ветки 

 
Piter   (2004-05-19 19:38) [0]

У кого нибудь есть? Типа
2567,56 - две тысячи пятьсот шестьдесят семь рублей 56 копеек

Какие алгоритмы не находил - со временем обнаруживалась ошибка. Причем, обнаруживалась в ходе эксплуатации рабочей программы, что очень неприятно, некоторые оффициальные документы с ошибками получились :( Некрасиво.

Может кто привести пример надежного проверенного алгоритма?


 
Palladin ©   (2004-05-19 19:42) [1]

что и в http://www.delphimaster.ru/cgi-bin/faq.pl?look=1&id=988619349&n=19 ошибка?


 
Piter ©   (2004-05-19 19:46) [2]

Не знаю, не проверял. Искал в FAQ, но не нашел, хотя точно помнил, что было.

Мне просто надо знать - кто реально использовал - алгоритм верный и безошибочный?
Не хочется опять через недели на документах обнаружить, что какое-то сочетание неправильно расшифровывается...


 
Piter ©   (2004-05-19 19:47) [3]

Я пользовался алгоритмами с базы готовых решений и функций.. и из интернета с других сайтов...


 
Piter ©   (2004-05-19 20:04) [4]

Посмотрел http://www.delphimaster.ru/cgi-bin/faq.pl?look=1&id=988619349&n=19

Ну что это такое...

1-ый вариант не работает с копейками. Даже проверять не стал.

2-ой вариант... ну как можно доверять алгоритму, где даже одиннадцать написано с одним "н".
Это легко правится, конечно. Но какие ошибки еще притаились...

и вообще, этот алгоритм я вроде видел в базе готовых решений. Там по-моему 11, 12, 13, 14 копеек пишется как копейки, например:
1,11 -> один рубль 11 копейки


 
dmk ©   (2004-05-19 20:12) [5]

За 6 лет эксплуатации моей базы не
было выявлено ни одной ошибки =)
Писал лет 6 назад. На D3.

function TextFromValue(value:extended):string;
var IntegerPartLen:integer;
   IntegerText:string;
   s1,s2,s3:string;
   StrAll:string[12];
   Counter:integer;
   st_1:string;//0-999
   st_2:string;//1 000-999 999
   st_3:string;//1 000 000-999 999 999
   st_4:string;//1 000 000 000 - 999 999 999 999

const
Array_1:array[0..9] of string =
   (""," îäèí"," äâà"," òðè"," ÷åòûðå"," ïÿòü",
    " øåñòü"," ñåìü"," âîñåìü"," äåâÿòü");

Array_1_2:array[0..9] of string =
   (""," îäíà"," äâå"," òðè"," ÷åòûðå"," ïÿòü",
    " øåñòü"," ñåìü"," âîñåìü"," äåâÿòü");

//...
Array_11_19:array[1..9] of string =
   (" îäèííàäöàòü"," äâåíàäöàòü"," òðèíàäöàòü",
    " ÷åòûðíàäöàòü"," ïÿòíàäöàòü"," øåñòíàäöàòü",
    " ñåìíàäöàòü"," âîñåìíàäöàòü",
    " äåâÿòíàäöàòü");
//...
Array_10_90:array[0..9] of string =
   (""," äåñÿòü"," äâàäöàòü"," òðèäöàòü",
    " ñîðîê"," ïÿòüäåñÿò"," øåñòüäåñÿò",
    " ñåìüäåñÿò"," âîñåìüäåñÿò",
    " äåâÿíîñòî");
//...
Array_E:array[0..9] of string =
   (""," ñòî"," äâåñòè"," òðèñòà",
    " ÷åòûðåñòà"," ïÿòüñîò"," øåñòüñîò",
    " ñåìüñîò"," âîñåìüñîò",
    " äåâÿòüñîò");

function IntegerPart(value:extended):string;
var Counter:integer;
   ResStr:string[1];
   ValueStr:string;
   r:string;
begin
Counter:=1;
r:="";
ValueStr:=FormatFloat("0.00",value);
repeat
  ResStr:=ValueStr[counter];
  Inc(Counter);
  if (ResStr = ",") or (ResStr = ".") then break;
  if ResStr = " " then continue;
  r:=r+ResStr;
until (ResStr = ",") or (ResStr = ".");
Result:=r;
end;
//................................................

//................
function Return_1(var sStr:string):string;
var vv:integer;
   code:integer;
   sCheck:string[2];
   cc:integer;
begin
Val(sStr[1],vv,code);
s3:=Array_E[vv];
//...
sCheck:=Copy(sStr,2,2);
Val(sCheck,cc,code);
if cc in [11..19] then
 begin
  s2:=Array_11_19[cc-10];
  Result:=s3+s2;
  exit;
 end else
 begin
   Val(sStr[2],vv,code);
   s2:=Array_10_90[vv];
   //...
   Val(sStr[3],vv,code);
   s1:=Array_1[vv];
   //...
 end;
Result:=s3+s2+s1;
end;//func 1

//.......
function Return_2(var sStr:string):string;
var vv:integer;
   code:integer;
   sCheck:string[2];
   cc:integer;
   LastWord:string;
begin
Val(sStr[1],vv,code);
s3:=Array_E[vv];
//...
sCheck:=Copy(sStr,2,2);
Val(sCheck,cc,code);
if cc in [11..19] then
 begin
  s2:=Array_11_19[cc-10];
  Result:=s3+s2+" òûñÿ÷";
  exit;
 end else
 begin
   Val(sStr[2],vv,code);
   s2:=Array_10_90[vv];        
   //...
   Val(sStr[3],vv,code);
   s1:=Array_1_2[vv];
   //...
 end;
LastWord:=" òûñÿ÷";
if vv = 4 then LastWord:=" òûñÿ÷è";
if vv = 3 then LastWord:=" òûñÿ÷è";
if vv = 2 then LastWord:=" òûñÿ÷è";
if vv = 1 then LastWord:=" òûñÿ÷à";
if (s3 = "") and (s2 = "") and (s1 = "") then lastWord:="";
Result:=s3+s2+s1+LastWord;
end;//func 1
//.......


 
dmk ©   (2004-05-19 20:13) [6]

//.......
function Return_3(var sStr:string):string;
var vv:integer;
   code:integer;
   sCheck:string[2];
   cc:integer;
   LastWord:string;
begin
Val(sStr[1],vv,code);
s3:=Array_E[vv];
//...
sCheck:=Copy(sStr,2,2);
Val(sCheck,cc,code);
if cc in [11..19] then
 begin
  s2:=Array_11_19[cc-10];
  Result:=s3+s2+" ìèëëèîíîâ";
  exit;
 end else
 begin
   Val(sStr[2],vv,code);
   s2:=Array_10_90[vv];
   //...
   Val(sStr[3],vv,code);
   s1:=Array_1[vv];
   //...
 end;
LastWord:=" ìèëëèîíîâ";
if vv = 4 then LastWord:=" ìèëëèîíà";
if vv = 3 then LastWord:=" ìèëëèîíà";
if vv = 2 then LastWord:=" ìèëëèîíà";
if vv = 1 then LastWord:=" ìèëëèîí";
if (s3 = "") and (s2 = "") and (s1 = "") then lastWord:="";
Result:=s3+s2+s1+LastWord;
end;//func 1
//.......

//.......
function Return_4(var sStr:string):string;
var vv:integer;
   code:integer;
   sCheck:string[2];
   cc:integer;
   LastWord:string;
begin
Val(sStr[1],vv,code);
s3:=Array_E[vv];
//...
sCheck:=Copy(sStr,2,2);
Val(sCheck,cc,code);
if cc in [11..19] then
 begin
  s2:=Array_11_19[cc-10];
  Result:=s3+s2+" ìèëëèàðäîâ";
  exit;
 end else
 begin
   Val(sStr[2],vv,code);
   s2:=Array_10_90[vv];
   //...
   Val(sStr[3],vv,code);
   s1:=Array_1[vv];
   //...
 end;
LastWord:=" ìèëëèàðäîâ";
if vv = 4 then LastWord:=" ìèëëèàðäà";
if vv = 3 then LastWord:=" ìèëëèàðäà";
if vv = 2 then LastWord:=" ìèëëèàðäà";
if vv = 1 then LastWord:=" ìèëëèàðä";
if (s3 = "") and (s2 = "") and (s1 = "") then lastWord:="";
Result:=s3+s2+s1+LastWord;
end;//func 1

//Main function body
//.......
var Txt:string;
   OneChar:string;
   s:string;
begin
Result:="Î÷åíü áîëüøîå çíà÷åíèå!";
if Value > 999999999999.99 then exit;

IntegerText := IntegerPart(value);
IntegerPartLen:=Length(IntegerText);
StrAll:="000000000000";
// Êîïèðóåì ñòðîêó çàäîì íàïåðåä
for Counter:=IntegerPartLen downto 1 do
 begin
  StrAll[(12-IntegerPartLen)+Counter]:=IntegerText[Counter];
 end;
//...
//Ðàçáèðàåì ÷èñëî ïî ðàçðàäàì
st_1:=Copy(StrAll,10,3);
st_2:=Copy(StrAll,7,3);
st_3:=Copy(StrAll,4,3);
st_4:=Copy(StrAll,1,3);
//...
txt:=Return_4(st_4)+Return_3(st_3)+Return_2(st_2)+Return_1(st_1);
if txt <> "" then
 begin
  OneChar:=txt[2];
  s:=AnsiUpperCase(OneChar);
  txt[2]:=s[1];
 end;
Result:=txt;
end;


 
Piter ©   (2004-05-19 23:37) [7]

было бы еще зашибенно, если текст был по русски, а не кракозябрами


 
Piter ©   (2004-05-19 23:37) [8]

было бы еще зашибенно, если текст был по русски, а не кракозябрами


 
dmk ©   (2004-05-20 00:56) [9]

Давай мыло. Вышлю по русски =)


 
Sergey13 ©   (2004-05-20 08:48) [10]

2Piter ©   (19.05.04 20:04) [4]
>ну как можно доверять алгоритму, где даже одиннадцать написано с одним "н".
Это легко правится, конечно. Но какие ошибки еще притаились...

Как можно доверять программе, написанной таким программистом, который не в состоянии проверить алгоритм (грамматические ошибки - неправильный алгоритм!!! 8-) готовой функции длиной в два экрана? И который "мучается" несколько лет от отсутствия "нормальной" реализации, вместо того, что бы написать свою за пол(часа,дня, недели, месяца, года?).


 
Думкин ©   (2004-05-20 09:31) [11]

> Sergey13 ©   (20.05.04 08:48) [10]

Поддерживаю.


 
kaif ©   (2004-05-20 12:13) [12]

Посмотри мой компонент TCurrencyInWords:
http://www.lclassic.ru/index6.htm
Он примитивный, но универсальный и работает, как танк.


 
Сергей Суровцев ©   (2004-05-20 13:14) [13]

А самый верный метод - хранить все слова, вместе с падежами в отдельном текстовом файле, а в программу зашить только базовый алгоритм.


 
Piter ©   (2004-05-20 21:48) [14]

Удалено модератором
Примечание: Повежливее


 
paul_k ©   (2004-05-20 22:02) [15]

Piter ©   (20.05.04 21:48) [14]
а задача действительно тривиальна. разбить число на тройки (начиная с хвоста) преобразовать каждую тройку и после нее вписать нужное (тысяч, миллионов и так далее) работы - на 40 минут.
1234432234 = 234 432 234 001
и переписать
1 миллиард 234 миллиона 432 тысячи 234
А тройки преобразовать к строчной записи -  вообще никаких проблем.
В принципе - лаба для 1-го курса тема - работа со строками.
С копейками ещё проще - там всего 2 разряда а если валюта не рубль, то допускается запись ХХ/100


 
Sergey13 ©   (2004-05-21 09:05) [16]

2Piter ©   (20.05.04 21:48) [14]
>Да иди ты.
Куда? Ну договаривай, договаривай? 8-)

>Я тебя не просил высказываться о моем уровне.
Просить необязательно. Я бывший тимуровец. 8-)

>Я просил алгоритм, проверенный уже. Задача стандартна и часто возникает. Я не собираюсь изобретать велосипед.
Ты просил не алгоритм (ты похоже не знаешь значения этого слова 8-), а готовый код, который хочешь без разбирательства вставить в свою программу. И хочешь что бы за тебя и проверку то сделал кто-то другой.
А про велосипед... Ты его даже собирать из готового набора деталей даже не хочешь.

>Если ты считаешь, что задача тривиальна - сделай сам. Потом выеживайся.
А я и сделал. Взял чей то, не очень удачный (для меня), код и доделал как мне надо. Давно уже. Ты тогда еще в начальной школе учился. И похоже учился так себе...


 
kinda   (2004-05-21 09:41) [17]

Давай мыло сброшу. Код писал сам и использую с начала
года ошибок пока не возникало.


 
Piter ©   (2004-05-22 00:30) [18]

Sergey13 (21.05.04 09:05) [16]

без комментариев. Я сделал выводы относительно тебя. Ты, наверняка, сделал относительно меня. На этом и разойдемся :)


 
kaif ©   (2004-05-22 00:48) [19]

Алгоритм простой, но не тривиальный. Задача не на 40 мин. Кто думает, что на 40 мин, пусть попробует сделать за 40 минут. Но чтобы не "приблизительно работало", а на самом деле и во всех случаях.
 2 Piter ©
 Скачай мой компонент и юзай. Он бесплатный и с исходным текстом. Для вывода чисел прописью в любой валюте нужно указать 8 свойств: 4 свойства для валюты и 4 свойства для ее центов.  Компонент позволяет, если надо, хоть в штуках выводить. А иногда надо. Например, в муторной накладной, которую обожает наш ГОСКОМСТАТ и правительство, нужно выводить число позиций прописью. Мой компонент позволяет это легко сделать. Просто вместо правил для "рублей" (рубль, рубля, рублей, мужской род) нужно указать правила для "позиций" (позиция, позиции, позиций, женский род) и он правильно выведет, например:
три триллиона пять миллиардов сто шесть миллионов пятьсот тринадцать тысяч триста двадцать одна позиция.
:)


 
Johnmen ©   (2004-05-22 01:56) [20]


function SpellPic(StDbl: double; StSet: integer): string;
          {format of StNum: string[15]= 000000000000.00}
const
 StMask = "000000000000.00";
var
 StNum     : string;   {StDbl -> StNum}
 PlaceNo   : integer;  {текущая позиция в StNum}
 TripletNo : integer;  {позиция имени обрабатываемого разряда (им.п. ед.ч.)}
 StWord    : string;   {результат}
//--------------------------------------------------
 procedure WordAdd(CodeNo: integer);
 var
   SymNo : integer;  {текущая позиция в массиве Sym}
   i, j  : integer;
 begin;
   Inc(CodeNo,CodeNo shl 1);  {* 3}
   for i:=1 to 3 do begin;
     Inc(CodeNo);
     SymNo:=ord(Code[CodeNo])-ord("Б"); if SymNo<0 then break;
     Inc(SymNo,SymNo shl 2);  {* 5}
     for j:=1 to 5 do begin;
       Inc(SymNo); if Sym[SymNo]=" " then break;
       StWord:=StWord+Sym[SymNo];
       end;
     end;
   StWord:=StWord+" ";
   end;
//--------------------------------------------------
 procedure Triplet;
 var
   D3         : integer;  {сотни текущего разряда}
   D2         : integer;  {десятки текущего разряда}
   D1         : integer;  {единицы текущего разряда}
   TripletPos : integer;  {смещение имени разряда для разных падежей}
 begin;
   Inc(PlaceNo); D3:=ord(StNum[PlaceNo])-ord("0");
   Inc(PlaceNo); D2:=ord(StNum[PlaceNo])-ord("0");
   Inc(PlaceNo); D1:=ord(StNum[PlaceNo])-ord("0");
   Dec(TripletNo,3); TripletPos:=2;                    {рублей (род.п. мн.ч.)}
   if D3>0 then WordAdd(D3+28);                                        {сотни}
   if D2=1 then WordAdd(D1+11)                                         {10-19}
   else begin;
     if D2>1 then WordAdd(D2+19);                                    {десятки}
     if D1>0 then begin;                                             {единицы}
       if (TripletNo=41) and (D1<3) then WordAdd(D1-1)   {одна или две тысячи}
                                    else WordAdd(D1+1);
       if D1<5 then TripletPos:=1;                      {рубля (род.п. ед.ч.)}
       if D1=1 then TripletPos:=0;                       {рубль (им.п. ед.ч.)}
       end;
     end;
   if (TripletNo=38) and (Length(StWord)=0) then WordAdd(50);     {ноль целых}
   if (TripletNo=38) or (D1+D2+D3>0) then                        {имя разряда}
     WordAdd(TripletNo+TripletPos);
   end;
//--------------------------------------------------
var
 i : integer;
begin;
 Move(Money[StSet,1],Sym[156],25);
 StNum:=FormatFloat(StMask,StDbl);

 PlaceNo:=0;
 TripletNo:=50;                                                       {47+3}
 StWord:="";                                             {будущий результат}

 for i:=1 to 4 do Triplet; {4 разряда: миллиарды, миллионы, тысячи, единицы}
 StWord:=StWord+StNum[14]+StNum[15]+" "; WordAdd(51);

 {Upcase первая буква}
 SpellPic:=AnsiUpperCase(StWord[1])+Copy(StWord,2,Length(StWord)-2);
 end;


Кто короче ?


 
Piter ©   (2004-05-22 11:52) [21]

kaif (22.05.04 00:48) [19]

Да, да. Спасибо, я уже скачал как только ты ссылку дал



Страницы: 1 вся ветка

Форум: "Потрепаться";
Текущий архив: 2004.06.06;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.54 MB
Время: 0.031 c
1-1084998259
greenrul
2004-05-20 00:24
2004.06.06
Удаление history+cache в Internet Explorer


6-1082459141
SergeySS
2004-04-20 15:05
2004.06.06
помогите с WebBrowser


3-1084825843
Dmitry Vyacheslavovich
2004-05-18 00:30
2004.06.06
Путь к базе данных


1-1085224983
ГудБой
2004-05-22 15:23
2004.06.06
Как поймать вход и выход dbgrid в режим InplaceEditor?


14-1084962975
ISP
2004-05-19 14:36
2004.06.06
Покупка Delphi. Что брать?





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский