» »

[C++] vprašanja

[C++] vprašanja

fx ::

Zanima me če c++ pozna log2 x ali pozna samo naravni in desetiški logaritem.

lp

"UNIX & C++ sta zakon"

OwcA ::

Ko poznaše enega, poznaš vse, če poznaš malo matematike. ;)
Otroška radovednost - gonilo napredka.

Zgodovina sprememb…

  • spremenilo: OwcA ()

Vesoljc ::

probaj prvega, potem pa klikni math.h
Abnormal behavior of abnormal brain makes me normal...

fx ::

C++ pozna samo naravni logaritem in logaritem z bazo 10.
Logaritme vem. Tako da bo treba pretvarjat, če se ne motim?

lp

"UNIX & C++ sta zakon"

Gundolf ::

C++ pozna samo naravni logaritem in logaritem z bazo 10.

C++ pozna le kar mu kdo pove :D

#include <cmath>
template <double N, class T>
T logn(T num) {
   if (N == 0) return 0;
   return (T)(std::log(num) / std::log(N));
}

fx ::

Zanimivo, ker tega nikjer ne piše, tako kot si mi ti napisla Gundolf.

Kaj jaz bi lahko z C++ naredil .ttf datoteko ali kaj podobnega ?


lp

"UNIX & C++ sta zakon"

Gundolf ::

Vse se da, ce se hoce. Ni ovir, sam da mas domislija! Sej, kam pa pridemo brez domislija ;)

OwcA ::

Če veš, da boš imel samo celoštevilske osnove (lahko, da s kakšnim prevajalnikom delujejo delne specializacije za vse tipe, na ICC 8 ne) je tu še kanček hitrejši način ;):
#ifndef LOGN_H
#define LOGN_H

#include <cmath>

template <int N, typename T>
	class LogN
{
public:
	static T value(T num)
	{
		return (T)(log(num) / log(N));
	}
};

template <typename T>
	class LogN<0, T>
{
public:
	static T value(T num)
	{
		return 0;
	}
};

#endif


Za kakšne res specializirane primere, ko veš, da bodo tudi argumenti logaritmu naravna števila in delaš s konstantami, lahko greš s specializacijami še korak dlje in prisiliš prevajalnik, da vse poračuna že med prevajanjem.

P.S. namen tega je bolj kot optimizacijo pokazati specializacije
Otroška radovednost - gonilo napredka.

Zgodovina sprememb…

  • spremenilo: OwcA ()

Gundolf ::

Samo nekaj se mi cudno zdi pri teh logaritmih. Mar ne racuna koprocesor (oziroma lahko recemo kar procesor) samo logaritmov z osnovo 2? Zakaj ima potem C oz. C++ implementirane ravno ostale logaritme? Morda pa se motim in je v procesorju tudi kaksen od logaritmov z osnovo e ali 10? Seveda govorim o x86 druzini, da ne bo pomote.

Ne se bat folk, prihaja tutorial o templateih

fx ::

Zakaj sta v obeh primerih uporabila cmath in ne math ?
Zanimivo je tudi da žepni računalniki tudi delajo samo z logrtitmi osnove e in 10.

lp

"UNIX & C++ sta zakon"

OwcA ::

@Gundolf: si prepričan, da ima x86 podporo za katerikoli logaritem (med OP kodami nisem našel nič)?

Nekaj algoritmov za računanje dvojiškega logaritma.

@fx: zato, ker piševa v C++, ne skrupucalo++ ;)
Otroška radovednost - gonilo napredka.

Zgodovina sprememb…

  • spremenilo: OwcA ()

fx ::

Aha potem bom jaz tudi pisal C++ in ne skropocalo++;)

lp

"UNIX & C++ sta zakon"

Zgodovina sprememb…

  • spremenil: fx ()

Gundolf ::

Ja 99.9% sem da ima podporo za log. Poleg tega pozna tudi nekaj konstant, npr log2(e).

Bom se jaz malce pobrskal po instrukcijah.

Gundolf ::

Ok, najdu: link, ce koga slucajno assembler zanima
FYL2X - log2(x)
Tko da bi blo dobr najdt kako knjiznico k zna to direkt uporablat, ce bi rabu velik logaritmov zracunat.

fx ::

logax = y //definicija logaritma to tako veste
ay = x

Štos je v tem če želim zakodirati y = 65 (znak A) pri log2 x 265 potem dobim tole cifro 3.689348815*1019, to vrednost ASCII tabela ne pozna.
Kaj narediti ali kaj mi predlagate da naj naredim, da nebom imel tako veliko cifro?
Možnost je da zamenjam osnovo, ali se lotim drugačnega kodiranja.

Jaz želim tako zakodirati, da noben znak ne bo imel vedno isti znak ampak vedno bo drugačen znak.
Primer :
Kodirano bsedeilo : BCDA
Dekodiarano besedilo : MAMA

lp

"UNIX & C++ sta zakon"

Gundolf ::

Poglej si RSA algoritem.
Tule je en primer.

RSA tudi uporablja potence. Prevelikih cifer se pa poenostavljeno povedano znebi tako da naredi modul (vzame ostanek po deljenju).

Ze vidim da bos naslednji teden spraseval, kako bi lahko nasel dovolj veliko prastevilo:D (ce ti bo RSA vsec seveda).

fx ::

Jaz sem ;( ker mi noče odpreti te strani.
Mogoče tebi odpre ali komu drugemu ?

lp

"UNIX & C++ sta zakon"

Gundolf ::

men tud ne odpre

ce te RSA zanima pogooglej pa bo

fx ::

Našo povezavo kjer je koda, samo jo treba malo predelati, samo končnice predprocesorskih direktiv, ker imajo končnico .h.

lp

"UNIX & C++ sta zakon"

Zgodovina sprememb…

  • spremenil: fx ()

Gundolf ::

Ne pozabi uporabiti std:: ali pa using namespace std.

Zgodovina sprememb…

  • spremenil: Gundolf ()

fx ::

RSA in C

lp

"UNIX & C++ sta zakon"

OwcA ::

@undolf: hvala, slep sem. ;)
Otroška radovednost - gonilo napredka.

fx ::

Ali C++ ne pozna matematičnega ukaza mod.
Gledal sem v cmath in math in pozna samo modf in fmod, kar ni to kar jaz iščem:
Primer, ki je prepisan iz tega file:
M = 9523 mod(187) = 90.

lp

"UNIX & C++ sta zakon"

OwcA ::

% mod
/ div

(ali pa je obratno ;) )
Otroška radovednost - gonilo napredka.

Zgodovina sprememb…

  • spremenilo: OwcA ()

Gundolf ::

Hehe fx, to je to kar ti isces. Fmod je pac mod ki deluje na floatih. Na intih lahko uporabljas %. problem z M = 95^23 mod(187) = 90. je v tem, da ne mores izracunati 95^23, ker je to prevelika cifra za integerje, v floatih (ali doublih) pa tega ne mores, ker rabis vedeti cisto vse decimalke (1.24235457568796806e2 je ze premalo natancno) Tako da ce zelis to izracunati bos moral kar rocno
int M = 95;
for (int i=1; i<23; ++i) {
   M = (M * M) % 187;
}

fx ::

Torej hočeš povedati moram vse ročno izračunat. Kako potem mi Računalo v win vse prikaže in tudi vse izračuna? Kaj potem ima ta za tipa da to lahko naredi?

lp

"UNIX & C++ sta zakon."

OwcA ::

Rabiš kakšno specializirano knjižnico za računanje z veliko natančnostjo (velikimi števili).

... ali pa uporabiš Mathematico ;)
Otroška radovednost - gonilo napredka.

Gundolf ::

Saj sem ti povedal kako to izracunas. Tudi racunalo v Winsih pravi da je 95^23 = 3,0735686772502389818218477637649e+45. Ta stevilka kot vidis ni cisto tocna (ceprav mislim da kalkulator hrani tudi bolj tocno stevilko, samo izpise je ne), saj jo lahko prevedes na (upam da se nisem ustel) 30735686772502389818218477637649 * 10^13. Se pravi, da ji manjka zadnjih 13 stevil, da bi bila popolnoma tocna. To se zgodi zato, ker double format ne zmore vecje tocnosti - enostavno nima dovolj bitov. Ampak ce racunas po nekem modulu bo cifra vedno manjsa od tistega modula in jo lahko izracunas na klasicen nacin.

Zdaj imas dve moznosti: mojo zanko ali pa knjiznico ki ti omogoca racunanje z vecjo natancnostjo. Sem pa preprican da pravi RSA algoritmi uporabljajo nekaj povsem tretjega in tako dosezejo racunanje se precej vecjih potenc (23 je res zelo zelo majhno prastevilo) v povsem sprejemljivem casu.

Ce torej hoces 128bitni RSA, bos rabil knjiznico, ki zna obdelovati 256bitne integerje (floating point stevilk ne rabis!), potenco po nekem modulu pa lahko z najhitrejsim algorimom ki si ga jaz trenutno predstavljam, izracunas rocno v 128 iteracijah.

Ce poenostavis in vzames max 16bitni kljuc bos vse lahko naredil ze z navadnim unsigned int, potenco pa lahko izracunas tudi s tisto najenostavnejso zanko.

64202 ::

Zdi se mi, da je tole precej popularno:
stran na www.swox.com

fx ::

Ni potrebno for znake ker lahko uporabim double pow(double x, double y)
Izracuna funkcijo xy.

lp

"UNIX & C++"

fx ::

#include <iostream>
#include <cmath>
using namespace std;

int main()
{
/*Prvo izberete dve prastevili p in q;
{2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 53, 59, 61, 67, 71, 73, 79, 
83, 89, 97, 101} - Tabela prastevil do 101;
*/
  int p;
  int q;
  int N;

  char znak;

  int M;
  int C;
  int e;
/*S paroma stevil e in N naredite svoj javni kljuc
Zasebni kljuc pa dobimo tako : e * d = 1 mod N (e in N - poznamo iz javnega kljuca);
Z uporabo evklidovega algoritma lahko izracunamo d;
Ko imamo C(zakodirana crka), d in N potem 
po formuli M = C^d(modN) dobimo crko katro smo zakodirali
*/
  cout << "Vnesi p    : "; 
  cin >> p;
  cout << "Vnesi q    : "; 
  cin >> q;
  N = p * q;
  cout << "p * q = N  : " << N << endl;
  cout << "Vnesi e    : "; 
  cin >> e;
   
  do
  {
    cout << "Vnesi znak : "; 
    cin >> znak;
    M = znak;
    cout << "ASCII koda : " << M << endl;
    C = M * M; 
    for (int i= 1; i < (e-1) ; ++i) 
    {
     C = (C * M) % N;
    }
    cout << "C          : " << C << endl
         << "Novi znak  : " << (znak = C) << endl 
         << "-------------------" << endl;
  }
  while (znak != 'Đ'); //Đ ne uporablja SSKJ 
return 0;
}


Evo to je program, ki kodira po RSA algoritmu C = Me(mod N). V programu so uporabljena ista imena spremenljivk za lažje razumevanje. Preverite ga lahko z istimi podatki, kot so navedeni v prejšnjih odgovorih. OwcA kako si to naredil, da ti je tako izpisal del programske kode, z poudarjenimi znaki.

lp

"UNIX & C++."

Zgodovina sprememb…

  • spremenil: fx ()

Gundolf ::

uporabi [ st.koda c ] in [ /st.koda c], pa brez presledkov za oklepajem in pred zaklepajem.

Si spremenil mnenje o funkciji pow? Ker v tvoji kodi ni o njej ne duha ne sluha ...

Zgodovina sprememb…

  • spremenil: Gundolf ()

fx ::

Vem da v kodi ni funkcije pow in mnenje sem tudi spremenil glede funkcije pow.

lp

"UNIX & C++"

fx ::

Kaj pa C++ ima prav funkcijo za Evklidov algoritem ali jo moram sam narediti ?

Prosil bi če sem napisal čisti C++ v prešnji kodi.

lp

"UNIX & C++"

OwcA ::

Kaj pa C++ ima prav funkcijo za Evklidov algoritem ali jo moram sam narediti ?

Gotovo ga je kdo že napisal, v standardnih knjižnicah pa ga ni.

Prosil bi če sem napisal čisti C++ v prešnji kodi.

Priden. ;)
Edinole ena estetska opazka. Proglasiti using namespace std v globalnem predelu je grdo, ker s tem vse svoje umotvore stlačiš v std, ki temu ni namenjen. Sicer je malo več klobasanja, ampak raje piši std::, pri kakšnih dalših funkcijah morda vseeno uporabiš using ampak znotraj funkcije.
Otroška radovednost - gonilo napredka.

fx ::

#include <iostream>

int main()
{
using namespace std;

//program

return 0;
}


Ker če napišem brez using namespace std potem mi javi napako cout, cin in endl niso definirani.
Je to tako prav ali ni kot sem navedel v primeru.

lp

"UNIX & C++"

Zgodovina sprememb…

  • spremenil: fx ()

mare_ ::

std::cout...

fx ::

Samo moram priznati, da koda ki ima na začetku funkcije
using namespace std
bolj pregledna, vsaj za mene in v literaturi je tudi tako uporalbjeno. Razen če se program, hitreje izvede, če uporablja std::cin... ?

lp

"UNIX & C++"

Gundolf ::

Ah, to nima nobene veze s hitrostjo izvajanja, Std je le del imena funkcij in razredov. Nima prav nobenih vplivov na izvajanje kode.

Jaz pa osebno raje uporabljam std::, sem se tako navadil. Oziroma napisem using std::cout; in potem uporabljam cout. Vsekakor pa dokler ne uporabljas vec knjiznic, katerih imena bi se lahko prekrivala je using namespace std cist ok.

Vesoljc ::

kaj pa hitrost prevajajnja?
Abnormal behavior of abnormal brain makes me normal...

CCfly ::

Throw distcc nodes at the problem :) (če se vam ne da googlati distcc razporedi prevajanje kode na več mašin v omrežju)
"My goodness, we forgot generics!" -- Danny Kalev

fx ::

#include <iostream>
#include <cmath>

int main()
{
using namespace std;
/*Prvo izberete dve prastevili p in q;
{2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 53, 59, 61, 67, 71, 73, 79, 
83, 89, 97, 101} - Tabela prastevil do 101;
*/
  int p;
  int q;
  int N;
  char znak;
  int d;
  int M;
  int C;
  int e;

  cout << "Vnesi p    : "; 
  cin >> p;
  cout << "Vnesi q    : "; 
  cin >> q;
  cout << "Vnesi e    : "; 
  cin >> e;
 
  N = p * q;
//uporabljen Evklidov algoritem za izracun d
  d = e - (((p-1)*(q-1)) % e);
  
  do
  {
    cout << "Vnesi znak : "; 
    cin >> znak;
    M = znak;
    cout << "ASCII koda : " << M << endl;
//for znka za kodiranje    
//uporabljena formula C = M ^ e (mod N)
    C = M * M;
    for (int y= 1; y < (e-1) ; ++y) 
      C = (C * M) % N;
    
    cout << "Novi znak  : " << (znak = C) << endl 
         << "-------------------" << endl;       

//for zanka za dekodiranje
//uporabljena formula M = C ^ (mod N);
    for (int x= 1; x < d; ++x) 
      M = (C * d) % N;
    
    cout << "Novi znak  : " << (znak = M) << endl 
         << "-------------------" << endl;  
  }
  while (znak != 'Đ'); //Đ ne uporablja SSKJ 
return 0;
}


Zgoraj je koda, ki kodira in dekodira po RSA algoritmu, samo je en problem, če so parametri nastavljeni p = 11, q = 17 in e = 7 potem mi zadeva deluje, kot mora, ko parametre spremenim pa ne deluje tako kot bi moralo, mislim, da mi evklidov algoritem ne deluje kot mora.

lp

"UNIX & C++"

OwcA ::

Čuden Evklidov algoritem imaš. Za trojico p=23, q=11, e=7 recimo ne dela.
Otroška radovednost - gonilo napredka.

fx ::

Saj sem v prešnjem postu reko da ne dela ko spremenim podatke.

lp

"UNIX & C++"

]Fusion[ ::

hmm kak si ti spravo evklidov algoritem v eno vrstico? Kolko jaz vem rabiš zanko itd.
Tak zgleda moj evklid(sem ga nekaj časa nazaj napisal in tudi ni verjetno najbolj optimiziran:P ):

#include <iostream.h>
#include <stdlib.h>

int main()
{
      int a, b, o = 1;

      cout << "Vpišite število a in b(med števili naredite presledek):";
      cin >> a >> b;

      while (o != 0)
            {
             o = a % b;
             a = b;
             b = o;
            }
      cout << "Največji skupni deljitelj števel je: " << a << endl;

      system("PAUSE");
      return 0;
}
"I am not an animal! I am a human being! I... am... a man!" - John Merrick

Gundolf ::

Hm, zakaj jaz v sivo-modri temi vidim dolgocasno sintaxo (vsebuje le navadne in bold fonte), v default bozicni temi pa je sintaxa tudi lepo pobarvana.

Is this a bug or a feature?

fx ::

]Fusion[ thx za kodo. Jaz imam eno program, ki sem ga sam napisal uporablja polja, in ni še v celoti, tako da bom tvojega vzel, če smem.
Če želite jo vam pokažem, samo ne da bi bili 8-O.

PS : Gundolf to je res, vse je lepše, tako ko bo ta čas mimo pustite barve, samo ozadje spremenite (božičeka s čim drugim zamenjajte).

lp

"UNIX + C++"

]Fusion[ ::

Jah to pa bojo mastni dnari za kodo :)
Ne ti kar uporabi, samo brez jamranja če ne bo delalo :)
"I am not an animal! I am a human being! I... am... a man!" - John Merrick

fx ::

#include <iostream>
#include <cmath>
using namespace std;

bool Evklid(int e, int N)
{
  int o = 1;
  while (o != 0)
  { 
    o = N % e;
    N = e;
    e = o;
  }
  if (N == 1) return true;
  if (N != 1) return false;
}
//glavni program 
int main()
{
  int p, q, N, d, M, C, e, PomSpre;
  char znak;
  bool yes_no = false;
  do 
  {
    cout << "Vnesi p....: "; 
    cin >> p;
    cout << "Vnesi q....: "; 
    cin >> q;
    cout << "Vnesi e....: ";
    cin >> e;
    yes_no = Evklid(e,((p - 1)*(q - 1)));
    if (yes_no != true)
      cout << "Najvecji skupni deljitelj ni enak 1!" << endl
           << "Isci novega!" << endl;
    else 
      d = ((p-1)*(q-1)+1) / e;
  }while(yes_no !=  true);
  cout << "Zasebni kljuc -> (" << p << " , " << q << ")" << endl;
  cout << "Javni kljuc -> (" << e << " , " << p*q << ")" << endl << endl;
  
  do
  { 
    cout << "Vnesi znak.: "; 
    cin >> znak;
    M = znak;
//uporabljena formula C = M ^ e (mod N)
    N = p * q; 
    C = 1; 
    for (int y = 1; y <= e ; ++y)
    {
      C = (C * M) % N;
      cout << C << " = " << M << "^" << y << endl; 
    }
    cout << endl
         << "M..........: " << M << endl
         << "----------------" << endl;
         M = 0; //zaradi preverjanja drugače bo to ločeno
//uporabljena formula M = C ^ (mod N);
      M = 1;
      for (int x = 1; x <= d; ++x)
      {
	M = (M * C) % N;
        cout << M << " = " << C << "^" << x << endl;
      }
    cout << "M..........: " << M << endl
         << "----------------" << endl;
  }
  while (znak != 'Đ'); //Đ ne uporablja SSKJ
return 0;
}


Evo to je koda, ki naj bi uporabljala RSA algoritem. Ima en problem
zadeva deluje ko uporabim p = 11, q = 17 in e = 7. Ker v RSA algoritemu je lepo napisano: da za število e moramo izbrati, tako število da imata e in produkt (p-1)*(q-1) največji skupnji deljitelj enak 1. To mi omgoča program od ]Fusion[-a.

Zakaj ne gre % če imam spremenljivko tipa double ?
Prevajalnik mi javi da je % samo za binarna števila int, ne kako tako, se ne spomnim več.


lp

"UINIX & C++"

]Fusion[ ::

Potem pa probaj spremenit v int. Mislim da je tak: (int)spremenjljivka
"I am not an animal! I am a human being! I... am... a man!" - John Merrick


Vredno ogleda ...

TemaSporočilaOglediZadnje sporočilo
TemaSporočilaOglediZadnje sporočilo
»

Program za C++ jezik

Oddelek: Programska oprema
232769 (1804) popaj113
»

Kako bi naredil en ultra simple programček?

Oddelek: Programiranje
492221 (1502) AtaStrumf
»

C++ & XP

Oddelek: Programiranje
241580 (1187) Exilian
»

C++ in pavza

Oddelek: Programiranje
161155 (916) napsy
»

c++ datoteke

Oddelek: Programiranje
463829 (3318) Vesoljc

Več podobnih tem